1 / 42

제 5 장 배열과 포인터

제 5 장 배열과 포인터. 포인터와 주소. 포인터 기억 장소의 위치 ( 주소 ) 를 저장하는 변수 포인터 변수의 선언 type * pointer-variable ; & 연산자 피연산자의 주소를 의미 반드시 기억 장소에 존재하는 객체를 피연산자로 가져야 함 상수 , 수식 , 레지스터 변수를 피연산자로 가질 수 없음. 포인터의 개념. p = &v;. 참조 연산자. * 연산자 포인터가 가리키는 대상을 접근하는데 사용 예 ) int x = 1, y = 2, z[10];

oral
Télécharger la présentation

제 5 장 배열과 포인터

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 제 5장 배열과 포인터

  2. 포인터와 주소 • 포인터 • 기억 장소의 위치(주소)를 저장하는 변수 • 포인터 변수의 선언 • type *pointer-variable; • & 연산자 • 피연산자의 주소를 의미 • 반드시 기억 장소에 존재하는 객체를 피연산자로 가져야 함 • 상수, 수식, 레지스터 변수를 피연산자로 가질 수 없음

  3. 포인터의 개념 • p = &v;

  4. 참조 연산자 • * 연산자 • 포인터가 가리키는 대상을 접근하는데 사용 • 예) int x = 1, y = 2, z[10]; int *ip; /* ip is a pointer to int */ ip = &x; /* now ip points to x */ y = *ip; /* y is now 1 */ *ip = 0; /* x is now 0 */ ip = &z[0]; /* now ip points to z[0] */

  5. 포인터 변수의 연산 • void형의 포인터를 제외한 모든 포인터는 가리키는 대상의 데이타형이 있음 • 예) 정수형 포인터 ip가 있을 때 *ip는 정수형 변수가 사용될 수 있는 모든 수식에 사용가능 *ip += 1; ++*ip; • void형 포인터: generic pointer • (*ip)++ 과 *ip++의 차이 • 포인터는 그 자체가 변수이므로 다른 포인터 변수의 값을 지정하는 지정문에도 사용됨 • 예) int i, *ip, *iq; ip = &i; iq = ip;

  6. 포인터를 이용한 인자 전달 • 호출 함수에서 피호출 함수이 변경한 변수의 결과를 사용하려면 값을 변경시키려는 인자를 포인터로 전달하여야 함 • swap 함수 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }

  7. swap(&i, &j)의 동작

  8. 포인터와 배열 • 포인터 • int *pa; • pa = &a[0]; • pa는 a의 첫번째 원소를 가리킨다 pa a : • pa+i는 pa에서 i 만큼 뒤에 있는 원소를 가리킨다. • pa가 a[0]을 가리키고 있다면 *(pa+i)는 a[i]를 참조

  9. 포인터와 배열(con’d) • 배열의 이름과 포인터의 유사점 • 배열의 이름은 배열의 첫번째 원소의 주소와 같다 • pa = &a[0]; 은 pa = a; 과 동일 • 배열 a의 원소 a[i]를 *(a+i)로 나타내는 것도 가능 • &a[i]와 a+i는 동일한 의미를 가짐 • pa[i]는 *(pa+i)와 같은 의미를 나타냄 • 배열의 이름과 포인터의 차이점 • 포인터는 변수이고 배열의 이름은 변수가 아니다 • 포인터의 경우는 다음과 같은 연산이 가능 pa = a; pa++; • 배열의 이름은 다음과 같은 연산이 허용되지 않음 a = pa; a++;

  10. 배열의 함수 이름 전달 • 배열의 이름을 함수의 인자로 전달 • 배열의 처음 원소의 주소가 전달이 된다 • 피호출 함수에서 배열 이름을 나타내는 인자는 포인터이다 int strlen(char *s) { int n; for (n = 0; *s != ''; s++) n++; return n; } • 함수를 정의할 때 형식 인자 char s[]와 char *s는 동등 • 그러나 char *s라고 선언하는 것이 더 좋음

  11. 주소 계산 • p가 포인터라면 p++는 기억 장소에서 바로 다음 원소를 가리키도록 p를 증가 • type *p; 일때 p++은 포인터는 1만큼 증가하지만 실제로 기억 장소의 주소는 sizeof(type)만큼 증가됨 • 포인터와 정수는 연산에서 호환되지 않음 • 0은 예외적으로 지정 또는 비교에 사용 • <stdio.h>의 심볼 상수 NULL은 포인터와 관련하여 0 대신에 사용 int *p; p = NULL; /* make p point to nothing */ if (p == NULL) ..... /* test if p is NULL pointer */ • 포인터 p에 NULL을 지정하면 포인터는 기억 장소의 어뗜 위치도 가리키고 있지 않다는 것을 의미

  12. 주소 계산(con’d) • 포인터에 대해 허용되는 연산 • 같은 형의 포인터에 의한 지정 • 포인터의 증감 • 포인터끼리의 비교 연산 • 포인터끼리의 뺄셈 int strlen(char *s) { char *p = s; while (*p != '') p++; return p-s; }

  13. char형 포인터 • 문자열 상수 • 문자 배열 • 함수의 인자로 사용되는 경우: 문자열의 시작 주소가 인자로 전달 printf("hello, world"); • char형 포인터의 초기화에 사용 char *pmessage; pmessage = "now is the time"; /* 문자열 복사와 다름 */

  14. char형 포인터(con’d) • 배열의 초기화와 포인터의 초기화 char amessage[] = "now is the time"; /* 배열 */ char *pmessage = "now is the time"; /* 포인터 */ amessage: pmessage: now is the time\0 now is the time\0

  15. 예제(strcpy 함수) /* strcpy: version using array subscript */ void strcpy(char *s, char *t) { int i = 0; while ((s[i++] = t[i++]) != '') ; } /* strcpy: version using pointer */ void strcpy(char *s, char *t) { while ((*s++ = *t++) != '') ; }

  16. 포인터 배열 • 포인터 배열 • 원소가 포인터인 배열 • 예) 문자열 저장

  17. 포인터 배열의 예제 #include <stdio.h> main() { static char *week[] = { "Sunday","Monday","Tuesday","Wednesday", "Thursday","Friday","Saturday"}; int k; for (k=0;k<7;k++) printf("week[%d]=%c, %s\n",k,*week[k],week[k]); }

  18. 다차원 배열 • 다차원 배열(multi-dimensional array) • 선언 방법 • type array-name[d1][d2] ......[dn]; • C는 다차원 배열을 행-열 순서로 저장 • 예를 들어 2차원 배열 int m[3][3]는 다음과 같이 저장됨

  19. 다차원 배열(con’d) • 다차원 배열을 인자로 갖는 함수의 형식 인자 선언 • 허용되는 인자 선언 void a(int m[3][3]); void a(int m[][3]); void b(f[4][2][3]); void b(f[][2][3]); void a(int (*m)[3]); => int (*m)[3]는 pointer to array of size 3을 의미 void b(int (*f)[2][3]); => int (*f)[2][3]는 pointer to array of 2d array of [2][3]을 의 미

  20. 포인터와 2차원 배열 • 2차원 배열 int a[10][20]; • a는 2차원 배열로서 10×20개의 정수를 저장할 수 있는 기억 공간을 차지 • a[row][col]에 해당하는 원소를 참조하기 위해 20×row+col의 위치 계산 • 포인터 int *b[10]; • b는 10개의 포인터만을 저장할 수 있는 기억 공간을 할당받음 • 각 행이 가리키는 배열의 길이가 각기 다를 수 있다

  21. 포인터와 2차원 배열(con’d) • 포인터와 2차원 배열의 기억 장소 사용 char *name[] = "Christoper", "Michael", "John", "Tom" ; char aname[][11] = "Christoper", "Michael", "John", "Tom" ;

  22. 포인터와 2차원 배열(con’d) char aname[][11] = {"Christoper", "Michael", "John", "Tom”} ;

  23. 명령행(command line) 인자 • 명령행 인자를 처리하기 위한 main함수의 형태 • main(int argc, char *argv[]) • argc는 명령행에서 입력된 토큰의 갯수를 의미 • argv는 입력된 각 토큰들의 포인터를 저장하고 있는 배열 • argc는 항상 1이상의 값을 갖는다. • argv[0]는 프로그램의 이름을 가리키 기 때문 • 명령행 입력: prog arg1 arg2 arg3 • argc는 4, argv는 다음과 같이 구성

  24. 명령행 인자 사용의 예 #include <stdio.h> main(int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) printf("argv[%d] = %s%s", i, argv[i], (i < argc-1) ? ", " : ""); }

  25. 제 6장 구조체와 공용체

  26. 구조체 • 구조체(structure) • 여러개의 서로 연관된 변수들을 하나의 단위로 묶어서 처리 • 구조체의 예 학생

  27. 구조체의 선언 • 선언 struct tag-name { type variable1; type variable2; ........... } ; • 예 struct student { int number; char dept[MAXDEPT]; char name[MAXNAME]; int year; char address[MAXADDR]; char phone[MAXPHONE]; } ;

  28. 구조체 변수 선언 • 구조체 변수 선언 • 구조체의 선언은 형(type)을 정의 • 구조체 선언의 오른쪽 • struct tag-name x, y, z ; • 태그(tag)의 사용 • 변수들의 리스트가 없는 구조체 선언은 메모리 할당을 하지 않고 구조체의 구성요소만을 기술 • 태그를 사용한 경우에는 추후 변수 선언 가능 struct point { int x; int y; } ; struct point pt;

  29. 구조체 변수 선언(con’d) • 태그를 사용하지 않은 경우 • 추후 변수 선언 불가능 struct { int x; int y; } pt; • 구조체 변수의 초기화 • 초기값에 의한 초기화 struct point pt = { 640, 480 } ; • 구조체 변수에 의한 지정이나 함수의 리턴값으로 초기화 가능

  30. 구조체 멤버 • 구조체 멤버의 참조 • structure-name.member • 예) printf("x = %d, y = %d", pt.x, pt.y); • 구조체의 중첩 정의 예) struct rect { struct point pt1; struct point pt2; } rectangle; • 멤버의 참조: rectangle.pt1.x, rectangle.pt1.y

  31. 구조체에 대한 연산 • 지정문에서 하나의 단위로 복사 • & 연산자를 사용하여 주소를 얻음 • 멤버를 참조 • 함수의 인자로 전달, 함수의 리턴값: 복사에 의해 전달 • 구조체는 비교에 사용될 수 없음

  32. 구조체와 함수 • 구조체를 리턴하는 함수 struct point makepoint(int x, int y) { struct point temp; temp.x = x; temp.y = y; return temp; } struct point pt1; pt1 = makepoint(0, 0);

  33. 구조체와 함수(con’d) • 구조체의 인자 전달 struct point addpoint(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return p1 } • 구조체의 포인터 • 구조체 전체를 복사하여 전달하는 것보다 포인터를 전달하는 것이 효율적 • 구조체의 포인터의 선언 struct point *pp; • 멤버의 참조 (*pointer-to-structure).member-of-structure pointer-to-structure->member-of-structure

  34. 구조체와 함수(con’d) • 구조체 포인터 사용의 예 struct point pt, *pp; pt = makepoint(0,0); pp = &pt; printf("Point is ( %d, %d )",(*pp).x, (*pp).y); struct rect r, *rp = &r; r.pt1.x, rp->pt1.x, (r.pt1).x, (rp->pt1).x => 동일한 참조

  35. 구조체와 배열 • 선언의 예 struct ename { char last[30]; char mi; char first[20]; } ; struct person { struct ename name; int serialno; char sex; } ; struct person employee[MAX]; • 원소의 접근 • employee[i].name.last • employee[i].serialno

  36. 자기 참조 구조체 • 구조체는 자기자신을 멤버로 가질 수 없음 • 자기 참조 구조체(self-referential structure) • 자기자신을 가리키는 포인터를 멤버로 가지는 구조체 • 리스트(list)나 트리(tree)와 같은 자료 구조를 구현에 사용 struct book { /* 자기 참조 구조체 */ char title[80]; char author[80]; struct book *nextbook; } ;

  37. sizeof • sizeof 연산자 • 컴파일시 대상의 크기를 계산하는 연산자 • sizeof object또는 sizeof(object) • 데이타형의 크기를 바이트 단위로 계산한 정수값을 의미 • ex) int n; sizeof(n) 또는 sizeof(int) => int형의 바이트 크기

  38. typedef • 새로운 데이타형을 정의하는데 사용 • typedef int Length; • int형과 동일한 Length라는 새로운 데이타형을 만드는 것 Length len, maxlen; Length *lengths[]; • typedef char * String; • char형의 포인터형에 해당하는 String형을 정의 String p, lineptr[10];

  39. typedef(con’d) • typedef와 #define의 차이점 • #define String char * • String p, lineptr[10]; => char * p, lineptr[10]의 의미를 나타냄 • typedef의 예 typedef struct { double real; /* 실수부 */ double imag; /* 허수부 */ } COMPLEX; COMPLEX complex_add(COMPLEX a, COMPLEX b) { a.real += b.real; a.imag += b.imag; return a; }

  40. 공용체 • 선언 union tag-name { type variable1; type variable2; ........... } ; • 구조체와 다른점: 공용체내의 멤버들은 동일한 기억 장소를 공유 • 공용체의 멤버를 참조하는 방법은 구조체와 동일 union-name.member union-pointer->member

  41. 공용체 사용예 #include <stdio.h> #define STRING 0 #define INTEGER 1 #define FLOATING 2 struct { int type; union { char *sval; int ival; float fval; } u; } val;

  42. 공용체 사용예(con’d) main() { ............... if (val.type == STRING) printf("Value = %s",val.u.sval); else if (val.type == INTEGER) printf("Value = %d",val.u.ival); else if (val.type == FLOATING) printf("Value = %f",val.u.fval); else printf("bad type : %d",val.type); ................ }

More Related