구조체

 

 

구조체의 형 선언과 멤버 참조

 

- 구조체는 배열처럼 여러 개의 변수를 묶어서 처리할 수 있는 방법을 제공

 

- 배열과 차이점은 다른 형태의 자료형도 함께 묶을 수 있다는 것이다

 

- struct예약어를 사용하여 구조체의 형태를 만든다

ex)

struct student{

int num;

double grade;

};    //세미콜론 꼭 붙여줘야 함

 

- 구조체 내의 멤버 참조 시 미리 선언해주어야 함

ex) struct student s;

 

- 구조체 내의 멤버들은 기억공간을 할당받지 않는다.

 

- 구조체는 사용자가 임의로 정의한 자료형

 

- 구조체 변수의 각 멤버를 참조하기 위해서 멤버참조 연산자 (.)을 사용

ex)

s.num=12;

s.grade=4.0;

 

예제 17-1) 구조체의 형 선언과 멤버 참조

과자 바사삭의 가격과 열량을 저장할 cracker구조체를 선언 후 가격과 열량을 키보드로 입력받아 화면에 출력

#include <stdio.h>

int main(){
 struct cracker{
  int price;
  int cal;
 };
 
 struct cracker c;
 printf("바사삭의 가격과 열량을 입력하세요 : ");
 scanf("%d %d", &c.price, &c.cal);
 
 printf("바사삭의 가격 : %d원", c.price);
 printf("바사삭의 열량 : %dkcal", c.cal);
 
 return 0;
}

결과

 

 

- 구조체의 멤버로 포인터 변수도 사용 가능하다.

 

- 포인터 변수를 멤버로 사용하는 경우 문자열을 간단히 연결할 수 있다.

 

- 하지만 문자열 저장을 위한 기억공간이 존재하지 않으므로 키보드로부터 새로운 문자열의 입력이 불가능하다.

 

- 구조체의 멤버로 다른 구조체를 사용할 수 있다.

ex)

struct profile{

int age;

double height;

char* np;

}

struct student{

struct profile pf;

int num;

int grade;

}

 

- 위의 경우 멤버참조를 두번하면 된다.

ex) s.pf.age=21;

 

예제17-2) 구조체 멤버의 참조

구조체의 포인터 멤버를 참조하여 키보드로부터 데이터를 입력받아 프로그램 실행하기

#include <stdio.h>
#include <stdlib.h>
struct profile{
 int age;
 double height;
 char* np;
};

struct student{
 struct profile pf;
 int num;
 double grade;
};

int main(){
 struct student s1;
 
 printf("나이를 입력하세요 : ");
 scanf("%d", &s1.pf.age);
 
 printf("키를 입력하세요 : ");
 scanf("%d", &s1.pf.height);
 
 s1.pf.np = (char*)malloc(sizeof(char));    //구조체의 포인터변수 멤버에 값을 입력하기 위해 동적할당을 해준다
 printf("이름을 입력하세요 : ");
 scanf("%s", s1.pf.np);
 
 s1.num=5;
 s1.grade=4.4;
 
 
 printf("이름 : %s\n", s1.pf.np);
 printf("나이 : %d\n", s1.pf.age);
 printf(" 키  : %d\n", s1.pf.height);
 printf("학번 : %d\n", s1.num);
 printf("학점 : %.1lf\n", s1.grade);
 
 return 0;
}

결과

 

 

- 구조체 변수를 선언하면 외부변수가 되므로 초기화를 해주지 않으면 모든 기억공간이 0으로 채워진다.

 

- 구조체 변수를 함수의 전달인자로 사용할 수 있다.

#include <stdio.h>
#include <stdlib.h>

struct student{
 int age;
};

struct student add(struct student);

int main(){
 
 struct student s1;
 s1.age = 21;
 printf("나이 : %d\n",s1.age);


 s1 = add(s1);    //함수 호출
 printf("나이 : %d", s1.age); 

 

 return 0;
}

struct student add(struct student s2){
 int a = 21;
 s2.age = a + 10;
 return s2;
}

결과

 

 

예제 17-3)구조체 변수를 전달인자로 받고 리턴하는 함수

student구조체 선언 후 평균 빼고 모두 초기화 해준다.

평균을 구하고 초기값을 리턴해주는 함수를 만든다.

메인함수에서 평균을 참조하여 출력한다.

#include <stdio.h>
#include <stdlib.h>

struct student{
 int num;
 char name[20];
 int score[5];
 double avg;
};

struct student average(struct student);

int main(){
 struct student s = {14113346, "이주연", {90, 95, 100, 90, 100}};
 
 s = average(s);
 
 printf("평균 : %.1lf", s.avg);
 
 return 0;
}
 
struct student average(struct student s){
 double average=0;
 
 printf("학번 : %d\n", s.num);
 printf("이름 : %s\n", s.name);
 printf("점수 : ");
 for(int i=0;i<5;i++){
  printf("%d\t", s.score[i]);
   average += s.score[i];
 }
 s.avg = average/5.0;
 printf("\n");

 return s;
}

결과

 

 

 

구조체 배열

 

- 같은 형태의 구조체변수가 많이 필요할 경우 배열을 선언하여 사용할 수 있다.

ex)

구조체:

struct adress{

char name[20];

int age;

char tel[20];

char addr[80];

}

메인에서 구조체배열 선언&초기화:

struct adress list[5] = { {"이름1", 나이1, "전화번호1", "주소1"},

    {"이름2", 나이2, "전화번호2", "주소2"},

    {"이름3", 나이3, "전화번호3", "주소3"},

    {"이름4", 나이4, "전화번호4", "주소4"},

    {"이름5", 나이5, "전화번호5", "주소5"}};

 

#include <stdio.h>

struct address{
 char name[20];
 int age;
 char tel[20];
 char addr[80];
};

int main(){
 struct address list[3]={{"이주연", 21, "010-1234-5678", "서울" },
       {"지한별", 21, "010-9876-5432", "대전"},
       {"홍서우", 21, "010-1111-2222", "서울" }};
 
 for(int i=0;i<3;i++){
  printf("%10s%5d%15s%20s\n", list[i].name, list[i].age, list[i].tel, list[i].addr);
 }
 return 0;
}

결과

 

 

 

구조체 포인터

 

- 구조체 전체를 가리키는 포인터

ex)

struct score{

int kor, eng, mat;

}

메인:

struct score a = {70, 90, 100};

struct score* sp = &a;

 

- 멤버참조 : (*sp).kor 또는 sp->kor

 

예제 17-4)구조체배열을 처리하는 함수

이름, 학점, 영어점수를 입력하여 엘리트의 데이터를 출력하는 프로그램

구조체 배열을 사용하여 키보드로부터 데이터를 입력받는다

엘리트는 학점 4.0이상 영어점수 900점 이상

#include <stdio.h>

struct profile{
 char name[20];
 double grade;
 int english;
};

void input_data(struct profile *);
void elite(struct profile *);

int main(){
 
 struct profile new_staff[5];
 
 input_data(new_staff);
 
 elite(new_staff);
 
 return 0;
}

void input_data(struct profile *pf){
 printf("이름, 학점, 영어점수\n");
 for(int i=0;i<5;i++){
  scanf("%s%lf%d", (pf+i) -> name, &(pf+i) -> grade, &(pf+i) ->english);
 }printf("\n");
}

void elite(struct profile *pf){
 for(int i=0;i<5;i++){
  if((pf+i)->grade >= 4.0 && (pf+i)->english >= 900){
   printf("이름 : %s, 학점 : %.1lf, 영어점수 : %d\n", (pf+i)->name, (pf+i)->grade, (pf+i)->english);
  }
 }
}

결과

 

 

 

 

공용체

 

- 공용체는 멤버들이 모두 같은 기억공간을 사용한다.

 

- 예약어 union사용

ex)union student{

int num;

double grade;

}

 

- 구조체와 비슷한 형태이다

 

#include <stdio.h>

union student{
 int num;
 double grade;
};
int main(){
 union student s = {315};
 
 printf("학번 : %d\n", s.num);
 s.grade = 2.1;
 printf("학점 : %lf\n", s.grade);
 printf("학번 : %d", s.num);
 
 return 0;
}

 

결과

 

학점에 데이터를 입력하여 학번의 데이터가 사라졌음을 알 수 있다.

 

 

열거형

 

- 기억공간에 저장될 데이터의 집합

 

- 예약어 enum사용

ex)enum seoson{spring, summer, fall, winter};

 

- 열거형 선언시 컴파일러는 실제로 멤버들을 정수형, 상수형으로 취급

#include <stdio.h>

enum season {spring, summer, fall, winter};    //열거형 사용

int main(){
 enum season ss;
 
 char* cp;
 int select;
 
 printf("계절을 선택하세요\n1.spring 2.summer 3.fall 4.winter\n");
 scanf("%d", &select);
 
 if(select==1) {ss = spring;}
 else if(select == 2){ss=summer;}
 else if(select == 3){ss=fall;}
 else if(select == 4){ss=winter;}
 else{printf("잘못된 번호입니다.");}
 
 switch(ss){
  case spring:
   cp = "inline"; break;
  case summer:
   cp = "swimming"; break;
  case fall:
   cp = "trip"; break;
  case winter:
   cp = "skiing"; break;
 }
 printf("나의 레저활동은 %s\n", cp);
 return 0;
 
}

결과

 

 

 

typedef를 사용한 형 재정의

 

- 자료형의 이름을 재정의하여 프로그램을 간결하게 작성할 수 있다.

#include <stdio.h>

 typedef struct{
 int num;
 double grade;
}Student;

void data_prn(Student *);
int main(){
 Student s={14113346, 4.5};    //재정의 사용
 
 data_prn(&s);
 
 return 0;
 
}
void data_prn(Student* sp){
 printf("학번 : %d\n", sp->num);
 printf("학점 : %.1lf\n", sp->grade);
}

결과

 

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(8)  (0) 2015.08.09
C언어 정리(7)  (0) 2015.08.07
C언어 정리(6)  (0) 2015.08.06
C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20

메모리 동적 할당

 

 

동적 할당 함수

 

- 정적 할당 : 프로그램 작성 시 필요한 기억공간의 크기를 결정하는것

 

- 동적 할당 : 메모리 낭비의 최소화를 위해 입력되는 데이터에 맞게 기억공간을 할당하는 것

 

- 동적할당을 하기 위해 malloc함수 사용(stdlib.h 헤더파일에 존재)

ex)

int* ip;

ip = (int*)malloc(sizeof(int));    //기억공간을 동적으로 할당받아 포인터 변수에 연결

 

- 프로그램 실행 시 메모리의 일정한 영역인 기억부류는 4가지가 있다.

     코드영역        :    실행 파일을 위한 영역

        스택           :    자동 변수 영역

기타 데이터 영역  :    외부 변수, 정적 변수 영역

          힙            :    동적 할당 메모리 영역

 

- 자동변수의 경우 함수가 리턴되면서 자동으로 기억공간을 회수하지만 동적할당은 그렇지 않다.

  따라서 특정 함수에 구속받지 않고 위치값만 알면 어디서나 참조가 가능하다.

  만약 동적할당된 메모리를 반납하려 한다면 free함수 사용한다.(stdlib.h 헤더파일에 존재)

ex)

free(ip);    //할당 받은 기억공간 반환

 

#include <stdio.h>
#include <stdlib.h>

int main(){
 int a = 10;
 int* ap;

 ap = (int*)malloc(sizeof(int));
 *ap = 20;
 printf("%d\n", a + *ap);
 free(ap);
 return 0;
}

결과 

 

- 메모리 할당 함수는 힙 영역에 원하는 크기의 메모리가 존재하지 않을 경우 널포인터를 반환

  따라서 프로그램이 중단되지 않게 하기 위해 malloc함수 호출 후 검사하여 널포인터인지 확인해야 함

 

예제 16-1) 일교차 출력 프로그램

최고기온과 최저기온을 저장할 기억공간을 동적으로 할당 후 일교차 출력

#include <stdlib.h>

int main(){
 
 int* ap;
 int* bp;

 ap = (int*)malloc(sizeof(int));
 bp = (int*)malloc(sizeof(int));
 

if(ap==0 && bp==0){    //malloc함수 호출 후 널포인터인지 확인

  printf("메모리가 부족합니다.\n");

}

else{
  printf("최고기온과 최저기온을 입력하세요\n");
  scanf("%d %d", ap, bp);

  printf("일교차는 %d도 입니다.", *ap - *bp);

}

 return 0;

 

결과

 

 

 

동적 할당 기억공간의 활용

 

- 주로 많은 기억공간을 한꺼번에 할당 받아서 배열로 사용하는 것이 효율적

 

- 할당 받은 기억공간의 시작 위치만 포인터변수로 가리키게 하면 포인터변수를 배열명으로 사용하여 배열과 같이 활용

 

- 동적 할당을 사용하여 문자열 처리하기

① 문자열을 입력받기 위해 충분히 큰 크기의 문자 배열 선언

② 문자열 입력 받기

③ 입력된 문자열의 길이를 계산해 크기에 맞게 기억공간을 동적으로 할당

④ 문자열을 할당받은 기억공간에 복사

 

#include <stdlib.h>
#include <string.h>


int main(){
 
 char temp[80];    //①
 char* str[3];
 
 for(int i=0;i<3;i++){
  printf("문자열을 입력하세요 : ");
  gets(temp);    //②
  str[i] = (char*)malloc(strlen(temp)+1);    //③
  strcpy(str[i], temp); //④
 }
 
 for(int i=0;i<3;i++){
  printf("%s\n", str[i]);
 }
 
 for(int i=0;i<3;i++){
  free(str[i]);
 }


 return 0;
}

결과

 

 

- 주의할 점은 포인터 변수나 포인터 배열을 자동변수로 선언하면 쓰레기값이 존재하게 되므로 선언과 동시에 널포인터로 초기화해주는 것이 좋다.

ex)

선언시 : char* str[100]={0};

저장된 문자열 출력시:

for(int i=0;str[i]!=0;i++){

printf("%s\n", str[i]);

}

 

예제 16-2) 행렬의 합

1  2   3  4        12 11 10 9         13 13 13 13

5  6   7  8    +   8  7  6   5    =   13 13 13 13

9 10 11 12        4  3   2  1         13 13 13 13    만들기

#include <stdio.h>
#include <stdlib.h>
int main()
{
 int* ap[3];
 int* bp[3];
 int* cp[3]; //행렬의 합
 for(int i = 0; i < 3; i++) { //메모리 동적 할당을 해준다
  ap[i] = (int *) malloc(sizeof(int));
  bp[i] = (int *) malloc(sizeof(int));
  cp[i] = (int *) malloc(sizeof(int));
 }
 for(int i = 0; i < 3; i++) {
  for(int j = 0; j < 4; j++) { // 각 요소의 합을 cp행렬에 저장한다.
   ap[i][j] = 4*i + 1*(j+1);
   bp[i][j] = 12 - 4*i - 1*j;
   cp[i][j] = ap[i][j] + bp[i][j];
  }
 }
 for(int i = 0; i < 3; i++) {
  for(int j = 0; j < 4; j++) {
   printf("%d\t", cp[i][j]);
  }
  printf("\n");
 }
 return 0;
}

결과

 

 

 

메인함수의 전달인자

 

- 명령행에서 프로그램을 실행시킬 때는 프로그램의 이름 외에도 프로그램에 필요한 정보를 함께 입력할 수 있는데 이들을 명령행 전달인자 라고 한다.

 

- 메인함수의 전달인자를 사용하는 방법

#include <stdio.h>

int main(int argc, char** argv){
 for(int i=0;i<argc;i++){
  printf("%s\n", argv[i]);
 }
 return 0;
}

위의 코드를 작성 후 cmd창을 켜 위의 코드가 저장되어 있는 경로로 이동한다.

그리고 (파일명) (전달인자) (전달인자) 를 입력한다.

결과

 

 

 

기타 동적 할당 함수

 

- calloc함수 : 배열을 할당 받고 초기화 한다.

#include <stdio.h>
#include <stdlib.h>

int main(){
 double* ap;
 ap=(double*)calloc(5, sizeof(double));
 for(int i=0;i<5;i++){
  printf("%lf\n", ap[i]);
 }
 return 0;
}

결과

 

 

- realloc함수 : 기억공간의 크기를 조절한다.

#include <stdio.h>
#include <stdlib.h>

int main(){
 int* ip;
 int size = 5;
 int cnt = 0;
 int num;
 
 ip=(int*)calloc(size, sizeof(int));
 while(1){
  printf("양수를 입력하세요");
  scanf("%d", &num);
  if(num<=0) break;
  if(cnt<size){
   ip[cnt++]=num;
  }
  else{
   size+=5;
   ip=(int*)realloc(ip, size*sizeof(int));
   ip[cnt++]=num;
  }
 }
 for(int i=0;i<cnt;i++){
  printf("%5d", ip[i]);
 }
 free(ip);
 return 0;
 
 return 0;
}

결과

 

프로그램을 종료시키지 않는 한 계속 양수를 입력할 수 있다.

 

 

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(9)  (0) 2015.08.09
C언어 정리(7)  (0) 2015.08.07
C언어 정리(6)  (0) 2015.08.06
C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20

응용포인터

 

 

이중포인터

- 포인터변수의 주소

#include <stdio.h>

int main(){
 int a = 1;
 int* ap;
 int** ap2;

 ap = &a;
 ap2 = &ap;
 
 printf("a\t%d\nap\t%d\nap2\t%d\n", a, ap, ap2);
 printf("*ap\t%d\n*ap2\t%d\n**ap2\t%d\n", *ap, *ap2, **ap2);


 return 0;
}

결과

 

 

 

이중포인터 배열

#include <stdio.h>

int main(){
 int a = 1, b = 2, c = 3;
 int* ap[] = { &a, &b,&c };
 int** ap2 = ap; //배열명이 배열 주소값

 printf("ap\t%d\nap2\t%d\n", ap, ap2);
 printf("*ap[0]:%d\t*ap[1]:%d\t*ap[2]:%d\n", *ap[0], *ap[1], *ap[2]);
 printf("*ap2[0]:%d\t*ap2[1]:%d\t*ap2[2]:%d\n", *ap2[0], *ap2[1], *ap2[2]);
 return 0;
}

결과

 

 

 

다중포인터(삼중포인터)

#include <stdio.h>

int main(){

 int a = 1;
 int* ap = &a;
 int** ap2 = &ap;
 int*** ap3 = &ap2;

 printf("a\t%d\nap\t%d\nap2\t%d\nap3\t%d\n", a, ap, ap2, ap3);
 printf("*ap\t%d\n*ap2\t%d\n*ap3\t%d\n", *ap, *ap2, *ap3);
 printf("**ap2\t%d\n**ap3\t%d\n", **ap2, **ap3);
 printf("***ap3\t%d\n", ***ap3);

 return 0;
}

결과

 

 

 

배열포인터

- 배열 전체를 가리키는 포인터

ex)

int ary[5]    =>    &ary : 배열포인터

 

- (배열포인터) + (주소값) = (주소) + (정수값*배열전체크기)

ex)

ary + 1 => (주소값) + (1*sizeof(ary[0])) = (주소값) + (1*4)

&ary + 1 => (주소값) + (1*sizeof(ary)) = (주소값) + (1*20) 

 

-2차원배열은 배열명이 배열포인터이다.

 

- 따라서 ary+1 => (주소값) + (1*sizeof(ary[0])) = (주소값) + (1*16) 이다.

ex)

ary[1][2]의 값을 배열포인터를 이용해 참조하여 찾기

 

①ary+1 = 100+(1*16)=116

②*(ary+1) = ary[1]

③*(ary+1)+2 = *(ary+1)+(2*4) = 116+8=124

  => 4 : sizeof(ary[1][0])

④*(*(ary+1)+2) = ary[1][2] = 7

 

-이차원 배열포인터 함수

#include <stdio.h>

void func(int(*)[3]); //매개변수는 배열포인터변수

int main(){

 int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };

 func(a); //전달인자는 배열명
 
 return 0;
}

void func(int(* ap)[3]){ 
 int i, j;

 for (i = 0; i < 2; i++){
  for (j = 0; j < 3; j++){
   printf("%d", ap[i][j]);
  }
  printf("\n");
 }
}

결과

 

 

 

함수포인터

- 함수명이 함수의 포인터이다.

 

-함수포인터는 함수형태만 같으면 기능에 상관 없이 저장이 가능하다.

ex)

int sum(int, int);        =>fp = sum;

int max(int, int);        =>fp = max;

 

#include <stdio.h>

int sum(int, int);

int main(){ 
 int(* sump)(int, int);
 int result;

 sump = sum;
 result = sump(10, 20);
 printf("result : %d\n", result);

 return 0;
}

int sum(int a, int b){
 return a + b;
}

결과

 

 

-함수포인터 프로그램

#include <stdio.h>

void func(int(*)(int, int));
int sum(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);

int main(){ 
 int select;

 printf("1.두 정수의 합\n");
 printf("2.두 정수의 차\n");
 printf("3.두 정수의 곱\n");
 printf("4.두 정수의 나누기\n");
 printf("선택하세요.");
 scanf_s("%d", &select);
 switch (select){
 case 1: func(sum); break;
 case 2: func(sub); break;
 case 3: func(mul); break;
 case 4: func(div); break;
 }
 return 0;
}
void func(int(*fp)(int, int)){
 int a, b;
 int result;
 
 printf("두 정수값을 입력하세요");
 scanf_s("%d%d", &a, &b);
 result = fp(a, b);
 printf("결과는 : %d\n", result);

}

결과

 

 

 

void포인터

- 가리키는 자료형에 대한 정보가 없는 포인터 => 모든포인터 저장 가능

 

- 사용시 형변환하여 사용

 

- 다양한 형태의 포인터를 전달인자로 받을 수 있는 함수를 만들 수 있다.

#include <stdio.h>
#include <string.h>

void func(char*, void*, void*);

int main(){ 
 int ia = 10, ib = 20;
 double da = 1.5, db = 2.5;

 func("int", &ia, &ib);
 printf("정수 교환 후 : %d, %d\n", ia, ib);
 func("double", &da, &db);
 printf("실수 교환 후 : %.1lf, %.1lf\n", da, db);

 return 0;
}

void func(char* type, void* vp1, void* vp2){
 int ip;
 int dp;

 if (strcmp(type, "int") == 0){ //type에 입력된 값이 int인 경우
  ip = *(int*)vp1;   //vp1을 int*로 형변환 후ip(=A)에 대입
  *(int*)vp1 = *(int*)vp2; //vp2를 int*로 형변환 후 형변환 한vp1에 대입
  *(int*)vp2 = ip;   //형변환한 vp2에 A대입
 }
 if (strcmp(type, "double") == 0){ //type에 입력된 값이 double인 경우
  dp = *(double*)vp1;    //vp1을 double*로 형변환 후ip(=A)에 대입
  *(double*)vp1 = *(double*)vp2; //vp2를 double*로 형변환 후 형변환 한vp1에 대입
  *(double*)vp2 = dp;    //형변환한 vp2에 A대입

 }

}

결과

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(9)  (0) 2015.08.09
C언어 정리(8)  (0) 2015.08.09
C언어 정리(6)  (0) 2015.08.06
C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20

자동변수(지역변수)

- 하나의 함수 내부에 선언한 변수

- 변수의 기억공간이 할당되는 시점은 각 변수가 속해 있는 함수가 호출되어 실행될 때이다

 

예제)13-1

메인함수에서 두 수를 입력받아 곱하는 프로그램

곱하는 작업은 리턴값이 없는 함수를 이용

#include <stdio.h>


void func(int *, int *, int *);     //함수선언

 

int main(){

int a, b, c;

 

printf("두 수를 입력하세요");
scanf_s("%d %d", &a, &b);

 

func(&a, &b, &c);
printf("%d", c);

 

return 0;

}

 

void func(int* a, int* b, int* c){
    *c = (*a)*(*b);   //두 변수 a,b를 곱한 값을 c에 대입한다.
}

 결과)


 

 

정적변수

- 기억공간의 생성과 초기화가 함수의 호출 횟수에 영향을 받지 않는 변수

- 선언 방법 ex) static int sum;

 

예제)13-2

메인에서 배열요소값 출력하는 프로그램

함수가 호출될 때마다 배열요소값 차례로 리턴하는 함수 이용

#include <stdio.h>

 

int* func();    //함수 선언

 

int main(){
    int i;
    int* p;
    for (i = 0; i < 5; i++){
        p = func();    //함수 대입
        printf("%d번째 배열 요소 : %d\n",(i+1), *p);    //배열 출력
    }
    

return 0;

}

 

int* func(){
    int array[] = { 1, 2, 3, 4, 5 };
    static int sum = 0;   //정적변수 선언
    sum++;
    return &array[sum-1];    //배열에 저장된 값 리턴
}

결과)



 

 

외부변수

- 변수를 함수 밖에서 선언한다.

 

예제)13-3

get_next 함수 : 현재 배열 요소의 값을 리턴하고 다음 배열 요소로 이동

get_before 함수 : 현재 배열 요소의 값을 리턴하고 이전 배열 요소로 이동

#include <stdio.h>

 

int array[] = { 1, 2, 3, 4, 5 };    //배열 선언

 

int get_next();        //함수 선언
int get_before();    //함수 선언

 

static int sum = 0;  //외부변수 선언

 

int main(){
 

printf("next함수 호출 : %d\n",get_next());

printf("next함수 호출 : %d\n", get_next());   
    

sum++;

 

printf("before함수 호출 : %d\n", get_before());
printf("before함수 호출 : %d\n", get_before());

 

return 0;

 

}

 

int get_next(){
    sum++;    //배열 인덱스 증가
    return array[sum-1];
}

 

int get_before(){
    sum--;    //배열 인덱스 감소
    return array[sum];
 
}

결과)

 

 

포인터 배열

- 포인터변수들로 만들어진 배열(문자열 상수)

 

예제)14-4

포인터배열을 사용해 가장 긴 단어 출력하기

#include <stdio.h>
#include <string.h>

 

int main(){

 

char* array[] = { "dog", "elephant", "monkey", "rabbit", "tiger" };   //포인터배열 선언
int i, j;
char* max = array[0];

for (i = 0; i < 5; i++){    //max보다 길이가 긴 배열요소를 max에 대입한다.
    if (strlen(array[i]) > strlen(max)) max = array[i];    //strlen() : 문자열 사이즈 측정함수
}
 
printf(max);
printf("\n");

 

return 0;

}

결과)

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(8)  (0) 2015.08.09
C언어 정리(7)  (0) 2015.08.07
C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20
C언어 정리(3)  (0) 2015.07.20

문자열의 처리

 

char* fruit = "apple";    //문자열 상수"apple"을 포인터변수에 대입

 

/* --------------------------------------------

for(int i=0;i<sizeof(fruit);i++){

printf("%s", fruit[i]);              //결과 : apple

}

--------------------------------------------*/

/* -------------------------------------------------------------------------------

fruit[0] = 'a'

fruit[1] = 'p'

fruit[2] = 'p'

fruit[3] = 'l'

fruit[4] = 'e'

--------------------------------------------------------------------------------*/

 

while(*fruit != \0){             //*fruit은 포인터변수 fruit(주소값)을 참조. 즉, apple과 같음

printf("%s\n", fruit);    //fruit에 저장된 값을 문자형으로 출력

fruit++;                       //주솟값을 1 증가

}

따라서 결과는

apple

pple

ple

le

e 

 

 

 

중요한 문자열 처리 함수

 

문자배열에 문자열상수를 저장하기

 

 

void user_strcpy(char* des, char* src)        //des : 선언한 배열 대입 & src : 저장할 문자열 상수 대입

{

while(*src != '\0'){                          

*des = *src;                                //선언한 배열 자리에 저장할 문자열요소 대입

src++;                                        //주소값 1씩 증가

des++;                                       //주소값 1씩 증가

}

*des='\0;                                       //마지막 자리 NULL값 대입

}

이 함수를 사용한다.

 

 

 

문자열 복사함수

 

"string.h"헤더파일에 선언되어있는 char* strcpy(char* , char* ) 함수를 사용한다.

 

...

#include<string.h>          //선언

...

char str1[20] = "apple";

char str2[20] = "banana";

char temp[20];                //임시 저장 배열 선언

 

strcpy(temp, str1);          //temp에 str1 저장

strcpy(str1, str2);           //str1에 str2 저장

strcpy(str2, temp);         //str2에 temp(원래 str1) 저장 

 

 

 

문자열의 길이를 계산하는 함수

 

unsigned int strlen(char* ) 함수를 사용한다.

 

char fruit[80] = "apple";

int len;

len = strlen(fruit);

printf("%d", len);                //5

printf("%d", sizeof(fruit));    //80

 

 

 

문자열을 비교하는 함수

 

"string.h"헤더파일에 선언되어 있는 int strcmp(char* str1, char* str2) 함수를 사용한다.

 

크기비교 

str1 > str2

str1 < str2

str1 == str2

리턴값

1

-1

0

 

...

#include<string.h>          //선언

... 

char str1[20] = "banana";

char str2[20] = "apple"; 

char temp[20];                    //임시 저장 배열 선언

int res;

 

res=strcmp(str1, str2);

if(res>0){                          //str1 > str2인 경우

strcmp(temp, str1);       //temp에 str1 저장

strcmp(str1, str2);        //str1에 str2 저장

strcmp(str2, str1);        //str2에 temp(원래 str1) 저장 

}

 

 

 

두 개의 문자열을 붙이는 함수

 

"string.h"헤더파일에 선언되어 있는 char* strcat(char* str1, char* str2)함수를 사용한다.

 

...

#include<string.h>          //선언

... 

char fruit[80] = "straw";

 

strcat(fruit, "berry"); 

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(7)  (0) 2015.08.07
C언어 정리(6)  (0) 2015.08.06
C언어 정리(4)  (0) 2015.07.20
C언어 정리(3)  (0) 2015.07.20
C언어 정리(2)  (0) 2015.07.20

포인터

 

int a=10;           //a에 10 저장

int* ap = &a;     //포인터변수 ap에 변수a의 주솟값 저장

    //=>int* 로 선언된 포인터 변수는 int형 변수의 주솟값만을 저장할 수 있다.

 

/* ---------------------------------------

↓주소값 : 48                          ↓주소값 : 52         

       52                    →                 10       

포인터변수 ap    (가리킨다)      int형 변수 a

--------------------------------------- */

 

printf("%d", a);        //a값 출력 52

printf("%d", *ap);    //printf("%d", *&a);와 같으므로 printf("%d", a);이다. 따라서 a값 출력 52

    //=>포인터 변수 앞에 *을 붙이면 포인터 변수가 가리키는 곳에 저장된 값을 가져온다.(*과 &가 상쇄됨)

printf("%u", ap);     //printf("%d", &a);와 같다. 따라서 a의 주솟값(ap)출력 48

printf("%u", &a);    //a의 주솟값을 출력 52

printf("%u", &ap);  //ap의 주솟값 출력 48

 

 

배열 포인터

 

int ary[5] = {10, 20, 30, 40, 50};

int* ap = &ary[0];     //&ary[0] = ary 이므로 ary[0] = *ary = *ap

 

/* -----------------------------------------------------------------------------------------------------

ary[0] = 10

ary[1] = 20

ary[2] = 30

ary[3] = 40

ary[4] = 50

↑주소값(ap) : 36        ↑40                           ↑44                          ↑48                          ↑52

  = &ary[0]                  = &ary[0]+1                = &ary[0]+2               = &ary[0]+3               = &ary[0]+4

------------------------------------------------------------------------------------------------------*/

 

printf("%u", ary);      //36

printf("%u", ary+1);   //40

printf("%u", ary+2);   //44

printf("%u", ary+3);   //48

printf("%u", ary+4);   //52

 

'Programming > C' 카테고리의 다른 글

C언어 정리(6)  (0) 2015.08.06
C언어 정리(5)  (0) 2015.07.20
C언어 정리(3)  (0) 2015.07.20
C언어 정리(2)  (0) 2015.07.20
C언어 정리(1)  (0) 2015.07.20

배열

 

1차원 배열 선언

int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};        //10개짜리 정수형 배열

 

a[10]배열

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

a[4] = 5

a[5] = 6

a[6] = 7

a[7] = 8

a[8] = 9

a[9] = 10

 

=> 배열의 인덱스값은 0부터!

 

 

2차원 배열 선언

int b[2][2] = {1, 2, 3, 4}       //2*2 정수형 배열

 

a[2][2]배열

a[0][0] = 1

a[0][1] = 2

a[1][0] = 3

a[2][2] = 4

 

 

문자열(문자 + 배열)

char c[]= "abcdefg\0";    //크기가 7인 문자형 배열 선언

NULL문자(\0)를 입력 함으로써 문자열의 끝을 알려줌

 

c[7]배열

c[0] = 'a'

c[1] = 'b'

c[2] = 'c'

c[3] = 'd'

c[4] = 'e'

c[5] = 'f'

c[6] = 'g'

'Programming > C' 카테고리의 다른 글

C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20
C언어 정리(2)  (0) 2015.07.20
C언어 정리(1)  (0) 2015.07.20
Exercise 10-1  (0) 2015.05.07

IF문

 

기본

if(조건)    //조건 : 예)부등식

{

//조건을 만족할 때 수행할 것들

}

else

{

//조건을 만족하지 않는 모든 경우에 수행할 것들

}

 

항상 실행

if(true)    //true대신 1 이상의 정수 가능

{

//수행할 것들

}

 

실행 안함

if(false)    //false대신 0 가능

{

 

}

 

 

SWITCH문

 

기본

switch(변수)

{

case 1 :     //첫 번째 경우

//수행할 것들

break;

case 2 :    //두 번째 경우

//수행할 것들

break;

default :    //첫 번째, 두 번째 모두 아닌 경우

//수행할 것들

}

 

 

WHILE문

 

기본

while(조건)

{

//수행할 것들

}

 

항상 실행

while(true)    //true 대신 1사용 가능

{

//수행할 것들

}

 

우선 do를  한 번 실행한 후 조건에 맞는 경우 do 실행

do

{

//수행할 것들

} while(조건);

 

 

FOR문

 

기본

for(초기 값 ; 조건식 ; 증감식)

{

//수행할 것들

}

 

계속 실행

for(;;)

{

//수행할 것들

}

'Programming > C' 카테고리의 다른 글

C언어 정리(4)  (0) 2015.07.20
C언어 정리(3)  (0) 2015.07.20
C언어 정리(1)  (0) 2015.07.20
Exercise 10-1  (0) 2015.05.07
Exercise 9-3  (0) 2015.05.07

 

 형식 지정자

의미

예 

%d 

정수를 10진수로 출력 

··· -2, -1, 0, 1, 2 ···

 %f

소수점이 있는 실수로 출력

 0.1, 0.05, 3.14

 %c

문자 형태로 출력

 a, C

 %s

문자열 형태로 출력

 sweet, honey

 

 

 

자료형

설명

바이트수 

범위 

정수형

부호있음

short

short형 정수 

2

-32768 ~ 32767

int

정수

4

-2147483648 ~ 2147483647

long

long형 정수

4

-2147483648 ~ 2147483647

부호없음

unsigned short

부호없는 short형 정수

2

0 ~ 65535

unsigned int

부호없는 정수

4

0 ~ 4294967295

unsigned long

부호 없는 long형 정수

4

0 ~ 4294967295 

char

문자 및 정수

1

-128 ~ 127

문자형

부호있음

unsigned char

문자 및 부호없는 정수

1

0 ~ 255

부호없음

float 

단일정밀도 부동소수점

4

1.2E-38 ~ 3.4E28

부동소수점형

double

두배정밀도 부동소수점

8

2.2E-308 ~ 1.8E308

 

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(3)  (0) 2015.07.20
C언어 정리(2)  (0) 2015.07.20
Exercise 10-1  (0) 2015.05.07
Exercise 9-3  (0) 2015.05.07
Exercise 9-1  (0) 2015.05.07

 

Exercise10-1.txt

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(2)  (0) 2015.07.20
C언어 정리(1)  (0) 2015.07.20
Exercise 9-3  (0) 2015.05.07
Exercise 9-1  (0) 2015.05.07
난수 10개 정렬  (0) 2015.05.07

+ Recent posts