Download presentation
Presentation is loading. Please wait.
1
제 3 장. 배열과 구조체 및 포인터
2
3.1 배열(Array)
3
3.1.1 배열의 선언(1/5) ■ 배열(array) ■ 배열 변수(array variable)
순서화된 자료의 항목의 집합 ■ 배열 변수(array variable) 하나의 값을 저장하는 변수가 아니고, 동일한 자료형의 값의 집합을 저장하고 선언하는(declaration)변수 ■ 배열 첨자(array subscript(index)) 배열변수 요소(정수, 상수, 산술식)의 수와 배열의 크기를 나타냄 C 언어에서는 다른 언어에서의 배열과 달리 첫 번째 요소가 0부터 시작된다. 배열 요소는 명기하면 명기된 요소수로 결정되나, 요소를 생략할 수 있다.
4
3.1.1 배열의 선언(2/5) ■ 배열 선언 방법 배열명 뒤에 대괄호([ ])를 하여 괄호 안에 원소 수를 기입
예) int score[40]; 최대 40개(0~39)에 대한 기억공간 확보 → 자료형은 int형 이외에도 char형, double형 등의 모든 형 (void형과 함수형은 제외)을 지정할 수 있다. 대괄호([ ])가 하나이면 1차원 배열, 2개이면 2차원 배열, 3개이면 3차원 배열이 된다.
5
3.1.1 배열의 선언(3/5) ■ int score[3]의 메모리 할당 예 형식) 기억클래스 자료형 배열명[첨자]; // 행
예) static int score[3]; //3행
6
3.1.1 배열의 선언(4/5) ■ 1차원 배열을 이용한 자료 할당 예(1/2)
1. #include <stdio.h> 2. 3. void main() { 4. int i, k[3]; // 3개의 정수의 배열 선언 5. k[0] = 10; // 3개의 원소에 값을 대입 6. k[1] = 20; 7. k[2] = 30; 8. 9. for (i = 0; i < 3; i++) // i = 0에서 2까지 3회 반복 10. printf("k[%d] = %d\n", i, k[i]); 11. }
7
3.1.1 배열의 선언(5/5) ■ 1차원 배열을 이용한 자료 할당 예(2/2)
번지가 2바이트 증가하는 이유는 C언어에서 int 자료형은 2바이트 크기를 갖고 있기 때문
8
3.1.2 배열의 초기화(1/3) ■ 배열의 초기화 집합 기호(‘{’, ‘}’)를 이용하여 초기화 (형식)
기억클래스 자료형 배열명[첨자]={값1, 값2, 값n....}; // 각 요소를 지정하여 대입 기억클래스 자료형 배열명[]={값1, 값2, 값n....}; // 기억공간의 개수를 적지않고 선안하는 값의 개수에 따라 기억공간이 설정되는 방법 (예) static int score[3]={89, 98, 75}; static int score[]={89, 98, 75};
9
3.1.2 배열의 초기화(2/3) ■ 배열의 초기화 방법을 이용한 예(1/2)
1. #include <stdio.h> 2. 3. void main() { 4. int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 5. int weeks[] = { 5, 5, 5, 4, 5, 5, 4, 5, 4, 4, 5, 4 }; 6. int index; 7. 8. for( index = 0 ; index < 12 ; index++ ) 9. printf("Month %d has %d days. \n", index + 1, days[index]); 10. printf("\n"); 11. for( index = 0 ; index < 12 ; index++ ) 12. printf("Month %d has %d weeks. \n", index + 1, weeks[index]); 13. }
10
3.1.2 배열의 초기화(3/3) ■ 배열의 초기화 방법을 이용한 예(2/2)
1. #include <stdio.h> 2. 3. void main() { 4. 5. int weeks[12] = {5, 5, 5, 4, 5, 5, 4, 5, 4, 4}; 6. int index; 7. 8. for( index = 0 ; index < 12 ; index++ ) 9. printf("Month %d has %d weeks. \n", index + 1, weeks[index]); 10. } weeks를 동적으로 선언하지 않고 12개로 고정한 후 값을 10개만 할당하였다. 따라서 마지막 11월과 12월의 weeks 값이 0으로 출력 된다.
11
3.1.3 배열의 종류(1/8) ■ 배열의 종류 1,2,3차원 배열 등이 있으며, 선언하는 자료형의 종류에 따라
정수형 배열과 문자형 배열이 있음. 2,3차원 배열은 1차원 배열을 확장한 개념으로 첨자의 개수만 늘려주면 됨
12
3.1.3 배열의 종류(2/8) ■ 2차원 배열(2-dimensional array)(1/2)
프로그램 언어에서는 배열의 배열(array of array)을 포함하는 어떤 형의 배열도 허용하며 2차원 배열을 행렬(matrix)이라고도 부른다. 2차원 배열은 행(row) 우선순위로 배열된다. 즉, 가로방향으로 먼저 자료를 할당한 후 다음 줄로 이동하여 좌측에서 우측 방향으로 전진하며 자료를 할당한다. (형식) 기억클래스 자료형 배열명[첨자, 첨자]; // 행, 열 (예) static char name[4, 4]; // 4행, 4열
13
3.1.3 배열의 종류(3/8) ■ 2차원 배열(2/2) name[4, 4]; 의 메모리 할당 첨자 주소
행우선 방식(Row-majored Order) → 포트란(FORTRAN)언어만이 열우선 방식을 사용한다.
14
3.1.3 배열의 종류(4/8) ■ 2차원 배열의 예 1. #include <stdio.h>
2. void main() 3. { 4. char name[5][10]; 5. int i; 6. 7. printf("이름 5개를 입력하세요...\n"); 8. for(i=0; i<5; i++) 9. scanf("%s", name[i]); 10. 11. printf("출력 합니다.\n"); 12. for(i=0; i<5; i++) 13. printf("%s\n",name[i]); 14. }
15
3.1.3 배열의 종류(5/8) ■ 다차원 배열(multi-dimensional array)
3차원 배열 이상을 말하는 것으로 2차원 배열은 한 장의 문서 이며, 3차원 배열은 각각의 문서가 모인 책으로 보면 될 것 이다.
16
3.1.3 배열의 종류(6/8) ■ 다차원 배열의 예(1/3) (형식)
기억클래스 자료형 배열명[첨자, 첨자, 첨자]; //면, 행, 열 (예) static char dept_student[2, 4, 4]; // 2면, 4행, 4열
17
3.1.3 배열의 종류(7/8) ■ 다차원 배열의 예(2/3) 1. #include <stdio.h> 2.
3. void main() { 4. 5. int a[2][3][4]; // 3차원 배열 a의 선언 6. int i, j, k; 7. a[0][0][0] = 9; a[0][0][1] = 2; a[0][0][2] = 4; a[0][0][3] = 3; 8. a[0][1][0] = 5; a[0][1][1] = 6; a[0][1][2] = 3; a[0][1][3] = 2; 9. a[0][2][0] = 3; a[0][2][1] = 7; a[0][2][2] = 9; a[0][2][3] = 5; 10. a[1][0][0] = 8; a[1][0][1] = 7; a[1][0][2] = 4; a[1][0][3] = 9; 11. a[1][1][0] = 4; a[1][1][1] = 5; a[1][1][2] = 5; a[1][1][3] = 5; 12. a[1][2][0] = 6; a[1][2][1] = 1; a[1][2][2] = 3; a[1][2][3] = 8; (계속)
18
3.1.3 배열의 종류(8/8) ■ 다차원 배열의 예(3/3) 13. 14. for(i = 0; i <= 1; i++) { 15. for(j = 0; j <=2; j++) { 16. for(k = 0; k <= 3; k++) 17. printf("%2d ", a[i][j][k]); 18. printf("\n"); 19. } 20. } 21. }
19
3.2 구조체(Struct)
20
3.2.1 구조체(STRUCT-ure)의 정의와 선언
하나의 명칭으로 불릴 수 있는 여러 변수들이 서로 다른 자료형을 가진 자료들의 모임 복잡한 자료를 통일적으로 처리하는 기능 (형식) struct 식별자로서 구조체명 { 멤버 1의 선언문; 멤버 2의 선언문; 멤버 3의 선언문; ... 멤버 n의 선언문; }; (예) struct list { char initial ; char sex ; int age ; <구조체 list의 메모리 할당>
21
3.2.2 구조체의 정의(1/3) ■ 구조체 선언(구조체와 변수 선언을 동시에 선언) (형식) struct 태그명 {
이미 선언된 구조체에 값을 할당하기 위한 것으로 일종의 변수를 선헌하는 것 ■ 구조체 선언(구조체와 변수 선언을 동시에 선언) (형식) struct 태그명 { 멤버 1의 선언문; 멤버 2의 선언문; 멤버 3의 선언문; ... 멤버 n의 선언문; } 구조체 변수 1, 구조체 변수 2, … ; (예) struct list { char sex; int age; } a, b, c;
22
3.2.2 구조체의 정의(2/3) ■ 구조체 선언(구조체를 선언하고 별도로 정의) ■ 구조체 선언의 예(1/2) (형식)
struct 태그명 구조체 변수 1, 구조체 변수 2, … ; (예) struct list a, b, c; ■ 구조체 선언의 예(1/2) 1. #include <stdio.h> 2. #include <string.h> 3. 4. void main() { 5. struct student{ 6. int number; 7. char name[20]; 8. int score; 9. } a; // a는 선언과 동시에 정의 10.
23
3.2.2 구조체의 정의(3/3) ■ 구조체 선언(2/2) 11. struct student b; // b는 선언 후 별도로 정의 12. 13. a.number = 1; 14. b.number = 2; 15. strcpy(a.name, "홍길동"); 16. strcpy(b.name, "Gil Dong Hong"); 17. a.score = 100; 18. b.score = 90; 19. 20. printf("number = %d\n", a.number); 21. printf("name = %s\n", a.name); 22. printf("score = %d\n", a.score); 23. printf("\n"); 24. printf("number = %d\n", b.number); 25. printf("name = %s\n", b.name); 26. printf("score = %d\n", b.score); 27. }
24
3.2.3 구조체 배열과 포인터(1/7) ■ 구조체 배열과 포인터 ■ 구조체 배열의 선언
배열 : 같은 형의 자료들만이 연속적인 공간에 저장되거나 할당 구조체 : 서로 다른 자료형의 변수들을 하나의 구조체명으로 묶어 선언 ■ 구조체 배열의 선언 구조체 선언과 동시에 정의할 수도 있으며, 구조체 선언 후 정의 시에 함께 선언할 수도 있음
25
3.2.3 구조체 배열과 포인터(2/7) ■ 구조체 배열의 선언(1/2) (형식) struct 태그명 { 멤버 1의 선언문
멤버 2의 선언문 멤버 3의 선언문 ... 멤버 n의 선언문 } 배열 ; 또는 struct 태그명 배열;
26
3.2.3 구조체 배열과 포인터(3/7) ■ 구조체 배열의 선언(2/2) (예) sturct list {
char name [10]; char sex; int age; } man [60]; // list형 구조체를 60개 소유하는 1차원배열 또는 struct list man[60] ;
27
3.2.3 구조체 배열과 포인터(4/7) ■ 구조체 배열의 초기화
배열의 원소 단위로 내부에 { }를 쓰며 1차원 구조체 배열의 배열크기는 생략이 가능 (형식) struct tag_name 배열 = { { … }, { … }, { … }, … } ; (예) struct list man []={ { ‘C', ‘M', 36 }, { 'K', 'F', 33 } { 'H', 'F', 8 } } ;
28
3.2.3 구조체 배열과 포인터(5/7) ■ 구조체 배열의 초기화 ※ 구조체 배열 선언과 동시에 변수의 값을 초기화하는 방법
(형식) struct 태그명 { 멤버 1의 선언문 멤버 2의 선언문 멤버 3의 선언문 ... 멤버 n의 선언문 } 구조체 배열 = {{..}, {..}, {..},…}; (예) sturct list { char name [10]; char sex; int age; } man []={ { ‘C', ‘M', 36 }, { 'K', 'F', 33 } { 'H', 'F', 8 } };
29
3.2.3 구조체 배열과 포인터(6/7) ■ 구조체 변수의 초기화에 배열을 사용한 예
1. #include <stdio.h> 2. 3. struct list { 4. char initial; 5. char sex; 6. int age; 7. }; 8. 9. void main(){ 10. int i; 11. struct list man[3] = { 12. {'C', 'M', 36}, 13. {'K', 'F', 33}, 14. {'H', 'F', 8} }; 15. 16. printf("init sex age \n"); 17. printf(" \n"); 18. for( i= 0; i<3; i++) 19. printf(" %c %c %2d \n", man[i].initial, man[i].sex, man[i].age); 20. }
30
3.2.3 구조체 배열과 포인터(7/7) ■ 구조체 변수의 초기화에 배열을 사용한 예
man[3]에 의해 구조체형이 3개 할당이 되며, 멤버 변수를 다시 구조체 배열에 하위로 메모리가 중첩되어 할당 <man[3]의 메모리 할당>
31
3.2.4 typedef와 구조체(1/3) ■ typedef 문 ■ typedef 정의
자료형의 이름을 사용자 마음대로 설정 하고자 할 때 사용되며, 또한 새로운 자료형을 정의할 경우에도 사용된다. ■ typedef 정의 #define mytype int (형식) typedef 자료형 변경할 형; (예) typedef double DWORD; ※ #define 명령어와 typedef 정의의 차이점 첫째, typedef는 #define과는 달리 심볼 명칭의 값으로 자료 type만을 취할 수 있다. 둘째, Typedef의 기능은 프로세서에 의해서 처리되는 것이 아니라 C컴파일러에 의해서 처리된다. 셋째, typedef는 #define보다 다양한 형태의 치환이 가능하다.
32
3.2.4 typedef와 구조체(2/3) ■ typedef를 이용한 구조체의 선언 (형식)
(예) typedef struct list man;man person; ※ 사용자 구조체 자료형 선언 예 1. #include <stdio.h> 2. 3. struct list{ 4. char initial; 5. char sex; 6. int age; 7. }; 8. 9. typedef struct list man; 10. (계속)
33
3.2.4 typedef와 구조체(3/3) ■ typedef를 이용한 구조체의 선언 11. void main() {
12. man person[] = { 13. { 'C', 'M', 36}, 14. { 'K', 'F', 33 }, 15. { 'H', 'F', 8 }}; 16. 17. man *ptr; 18. 19. printf("initial sex age \n"); 20. printf(" \n"); 21. 22. for(ptr=person; ptr<person+3; ptr++) 23. printf(" %c %c %2d \n", (*ptr).initial, (*ptr).sex, (*ptr).age); 24. }
34
3.2.5 공용체(1/3) ■ 공용체(Union) union을 사용하며, 가장 큰 멤버의 메모리를 할당한다.
즉, 하나의 메모리를 공유한다는 개념을 갖는다. union list { char a, int b, float c} man; <공용체의 메모리 할당>
35
3.2.5 공용체(2/3) ■ 구조체와 공용체의 차이 구조체와 공용체는 비슷한 형식을 취하지만 선언문자가 다르며
메모리 사용이 다르다. 구조체는 struct를 이용하고, 공용체에서 는 union을 사용한다. ※ 구조체와 공용체 사용의 차이 예 1. #include <stdio.h> 2. 3. struct s_tag { 4. char sc; 5. int si; 6. float sf; 7. }sx; 8. 9. union u_tag { 10. char uc; 11. int ui; (계속)
36
3.2.5 공용체(3/3) ■ 구조체와 공용체의 차이 12. float uf; 13. }ux; 14. 15. void main(){ 16. int i, j; 17. 18. i = sizeof(sx); 19. j = sizeof(ux); 20. 21. printf("struct --- %d \n", i); 22. printf("union --- %d \n", j); 23. } struct의 sx의 크기 : char sc(1)+int si(2)+float st(4) == 7byte union의 un의 크기 : float uf(4) == 4byte(나머지는 공유) ∴ struct sx > union un
37
3.3 포인터(Pointer)
38
3.3 포인터(1/4) ■ 포인터 ■ 포인터의 정의 자료구조를 이용한 프로그래머의 가장 중용한 도구로 다음과
같은 경우에 사용된다. - 호출 프로그램 내에서 변수를 변경할 수 있는 함수를 구축할 때, - 배열 처리 함수내의 메모리를 동적으로 배열할 때, - 연결 리스트와 같은 자료 표현을 구축할 때 등이다. ■ 포인터의 정의 - 변수이거나 또는 기억장치 위치의 주소를 표현하는 수식 - 자료형에 의하여 직접 제어되는 점이 주소와 다르다. - 접근(access) 속도가 빠름. - 프로그램에서 전역변수(global variable)를 사용하지 않고 부함수(sub-function)에 있는 변수의 값을 변경시킬 때에는 반드시 포인터를 사용해야 한다. - 포인터는 임의의 대상을 가르키는 것이므로 재귀적 지정이 가능하다.
39
3.3 포인터(2/4) ■ 메모리상의 변수와 주소의 관계 변수 p에 변수 a의 주소가 들어있으므로,
변수 c의 주소로 하면 p=&c로 됨. ∴ p = 8&c
40
3.3 포인터(3/4) ■ 포인터의 선언 ■ *p = 8&c 프로그램 예 (형식) 자료형 *포인터변수명;
포인터변수명 = &일반변수명; *포인터변수명 = 일반변수명 (예) int num, *p_num; //p_num은 주소를 저장하는 포인터형 변수 p_num = # //p_num에 num의 주소값 할당 *p_num = num; //p_num의 주소에 num값 할당 ■ *p = 8&c 프로그램 예 1. #include <stdio.h> 2. 3. void main() { 4. int a, b, c; 5. int *p; (계속)
41
3.3 포인터(4/4) 6. 7. a = 100; 8. b = 200; 9. p = &c; 10. 11. *p = a + b;
12. 13. printf("a(%d) + b(%d) = *p(%d) \n", a, b, *p); 14. printf("&a : %x\n&b : %x\n&c : %x\n p : %x\n&p : %x\n", &a, 15. &b,&c, p, &p); 16. }
42
3.3.1 포인터 연산(1/6) ■ 포인터의 연산 포인터의 연산에는 할당연산, 사칙연산, 증감연산이 있으며,
포인터의 사칙연산은 메모리 번지의 이동을 의미하는 것으로, 포인터의 연산은 포인터의 위치를 이동시키는 것을 의미한다. ※ 포인터에 단일 데이터를 할당 - 포인터에 단일 데이터를 할당하기 위해서는 & 연산자를 사용 - int형으로 포인터 p와 단일 데이터 d를 설정하고 단일 데이터 d를 &연산자를 이용하여 포인터 p에 할당 (예) (int *p, d) p = &d;
43
3.3.1 포인터 연산(2/6) ※ 포인터에 배열 데이터를 할당 - 포인터에 단일 데이터를 할당하기 위해서는 변수명 사용
- 포인터에 단일 데이터를 할당하기 위해서는 변수명 사용 - int형으로 포인터 p와 배열 d[4]를 설정하고 배열 d를 포인터 p에 할당하면 그 포인터는 그 배열의 첫 메모리 번지를 가르킨 다. 배열은 정적인 성격을 가지는 반명, 포인터는 동적인 성격을 갖기 때문이다. (예) (int *p, d[4]) p = d; - 포인터가 가리키는 데이터의 값을 얻고자 할 경우 * 연산자를 사용한다. int형으로 포인터 p와 단일 데이터 d를 선언한 뒤, 포인터 p가 가리키는 데이터 값을 d에 할당한다. (예) (int *p, d) d = *p;
44
3.3.1 포인터 연산(3/6) ※ 포인터의 사칙연산 - 해당데이터를 포인터형 만큼 이동하는데 사용
- 해당데이터를 포인터형 만큼 이동하는데 사용 - p=p+1은 현재 포인터의 데이터형 만큼의 증가를 의미 - 정해진 포인터 데이터형(int,char) 만큼 메모리 이동이 이루어짐 (예) p = p+1, p = p+3000, p = , p = p-3 ※ 포인터의 사칙연산(예) 1. #include <stdio.h> 2. 3. void main() { 4. char vc='H', *pvc; 5. int vi=1, *pvi; 6. float vf=3.14, *pvf; (계속)
45
3.3.1 포인터 연산(4/6) ※ 포인터의 사칙연산(예) 7. 8. pvc=&vc; 9. pvi=&vi;
10. pvf=&vf; 11. 12. printf("\n pvc-1=%u, pvc=%u, pvc+1=%u", pvc-1, pvc, pvc+1); 13. printf("\n pvi-1=%u, pvi=%u, pvi+1=%u", pvi-1, pvi, pvi+1); 14. printf("\n pvf-1=%u, pvf=%u, pvf+1=%u", pvf-1, pvf, pvf+1); 15. }
46
3.3.1 포인터 연산(5/6) ※ 포인터의 증감연산 - 포인터 변수의 증가는 해당 포인터의 이동을 의미
- 포인터 변수의 증가는 해당 포인터의 이동을 의미 - p++는 포인터 p가 포인터형만큼 증가한 것 - *p++는 포인터 p의 메모리 번지가 먼저 증가하고 증가된 메모리 번지내의 데이터 값이 *p++이다. (예) p++, *p++ - (*변수)형태의 증가는 해당 데이터가 증가된다. 메모리 번지의 이동 없이 메모리 번지에 해당하는 값만 증가하는 것이다. (예) (*p)++
47
3.3.1 포인터 연산(6/6) ※ 포인터의 증감연산(예) 1. #include <stdio.h> 2.
3. void main() 4. { 5. int a, b, c; 6. int *p, *q; 7. 8. a = 100, b = 200; 9. p = &a, q = &b; 10. c = ++(*p) + ++(*q); // ++ 연산자에 의해 1씩 증가 11. 12. printf("%d + %d = %d\n", a, b, c); // a = 101, b = 201 13. }
48
3.3.2 포인터의 종류(1/6) ■ 문자(char) 포인터 문자 혹은 문자의 주소를 가르키는 것
주로 문자열을 컨트롤 할 경우에 사용 (형식) char *포인터변수명; //선언 포인터변수명 = 배열명; //배열을 포인터로 받기 (예) char *p; char univ[5]={"Hankook"}; p = univ;
49
static char str []="Lee";
3.3.2 포인터의 종류(2/6) ■ 문자(char) 포인터 ※ 문자열의 배열과 포인터 변수의 차이점 문자열의 배열 포인터 변수 선언방법 char str[]; char *str 초 기 화 static char str []="Lee"; char *str = "Lee"; 자료길이 고정 가변 요소참조 str[i] (i=0, 1, 2, 3…) *(str +i) (i=0, 1, 2, …) 값 할당 str[0]='C';… str= "POINTER" 시작번지 str 번지연산 불가능 가능 (예: str++) 속 도 포인터 변수보다 느리다
50
3.3.2 포인터의 종류(3/6) ■ 정수(int) 포인터 메모리 할당 방법이 char 포인터와 다름
(형식) int *포인터변수명; //선언 포인터변수명 = 배열명; //배열을 포인터로 받기 (예) int *p; int univ[2]={99, 100}; p = univ;
51
3.3.2 포인터의 종류(4/6) ■ 정수(int) 포인터 ※ int 포인터의 메모리 할당
52
3.3.2 포인터의 종류(5/6) ■ 실수(float) 포인터 4(8)바이트에 1개의 float형 자료가 할당 (형식)
포인터변수명 = 배열명; //배열을 포인터로 받기 (예) float *p; float pi[2]={3.14, }; p = pi;
53
3.3.2 포인터의 종류(6/6) ■ 실수(float) 포인터 ※ float 포인터의 메모리 할당
54
3.3.3 포인터와 배열(1/3) ■ 포인터 배열 배열의 크기로 조작되는 모든 배열 처리 동작은 메모리에 접근하기 위해 사용된다는 점에서 포인터에 의해서도 처리가 가능하다. 포인터 배열의 의미는 메모리 번지를 지시하는 포인터들이 여러 개가 존재한다는 것으로 포인터 자체가 배열로 존재한다는 말이 되는 것이다. (예) int *p[5], data[5][10]; p[0] = data[0], p[1] = data[1];
55
3.3.3 포인터와 배열(2/3) ■ 포인터 배열 ※ 메모리 할당 예
56
3.3.3 포인터와 배열(1/3) ■ 포인터 배열 ※ 포인터와 배열을 사용한 예
1. #include <stdio.h> 2. 3. void main() { 4. char *str[3]; // 포인터 배열 변수 선언 5. int i,j; 6. str[0] = "COMPUTER"; 7. str[1] = "HARDWARE"; // 문자열의 대입 8. str[2] = "SOFTWARE"; 9. 10. for(i=0; i<2; i++) { 11. for(j=0; j<=7; j++) 12. printf("*str([%d] + %d) 〓> %c \n", i, j, *(str[i] +j)); 13. } 14. for(i=0; i<=2; i++) 15. printf("\n str[%d] 〓> %s", i, str[i]); 16. }
57
3.3.4 다중 포인터 배열(1/2) ■ 다중 포인터 배열 포인터 배열을 2차원 이상으로 환장한 것 (형식)
자료형 *포인터변수명[첨자][첨자]; (예) char *char_p[5][5]
58
3.3.4 다중 포인터 배열(2/2) ■ 다중 포인터 배열 ※ 2차원 포인터 배열의 메모리 할당
59
3.3.5 포인터의 포인터 ■ 포인터의 포인터 포인터 자료를 가리키는 포인터라는 의미 (형식) 자료형 **포인터변수명; (예)
char data[], *p[], **double_p; p=data; double_p = p; ※ 포인터의 포인터와 포인터, 배열과의 관계
60
3.3.4 다중 포인터 배열(1/2) ■ 포인터의 포인터 ※ 포인터의 포인터와 포인터, 배열과의 관계 예
1. #include <stdio.h> 2. 3. void main() { 4. int data, *p, **pp; 5. 6. data=100; 7. p=&data; 8. pp=&p; 9. 10. printf("\ndata : %d, &data : %u", data, &data); 11. printf("\n *p : %d, p : %u, &p : %u", *p, p, &p); 12. printf("\n**pp : %d, *pp : %u, pp : %u, &pp : %u", **pp, 13. *pp, pp, &pp); 14. }
61
3.3.4 다중 포인터 배열(2/2) ■ 포인터의 포인터 ※ 메모리 할당
°p=&data : p에 data의 위치를 저장(6672) °*p=*(&p) : p에 저장된 값(6672)이 가리키는 주소에 저장된 값(100) °**pp=*(*(&p) : pp에 저장된 값(6670)이 가리키는 곳의 값(6672)이 가리키는 곳에 저장된 값(100)
62
3.4 배열을 이용한 희소행렬(Sparse Matrix)
63
3.4 배열을 이용한 희소행렬(1/7) ■ 삼각형 배열(triangular array) ■ 희소 배열(sparse array)
대각선을 기준으로 오른쪽 또는 왼쪽 부분의 모든 원소들의 0의 값을 갖는 배열 - 왼쪽만 0으로 채워져 있을 경우 상위 삼각꼴(upper-triangular) - 오른쪽만 0으로 채워져 있을 경우 하위 삼각골(lower-triangular) - 대각선의 원소도 0의 값을 가질 경우 엄격한 삼각형 배열(strictly triangular array)이라 한다. ■ 희소 배열(sparse array) 전체 원소를 보았을 때, 상대적으로 원소의 값이 많은 배열 희소행렬을 저장할 때는 행의 인덱스, 열의 인덱스, 원소의 값으로 표현한다. 저장할 때는 인덱스 값이 따라 순서를 결정 하고 행이 같을 경우는 열의 인덱스의 순서에 따라 원소를 저장한다.
64
3.4 배열을 이용한 희소행렬(2/7) ■ 희소배열(삼각꼴) A(1, 1) ⇒ B(1) A(1, 2) ⇒ B(2) :
A(1, N) ⇒ B(N) A(2, 2) ⇒ B(N+1) A(N, N) ⇒ B(N(N+1)/2) 상위 삼각배열 A의 경우 인덱스 범위가 1에서 N(N+1)/2인 일차원 배열 B에 행 위주로 저장한다면 다음 그림과 같이 저장 될 것이다. (N :행의 수)
65
3.4 배열을 이용한 희소행렬(3/7) ■ 희소 행열(sparse matrix) 원소 행 열 원소의 값 B(1) B(2)
5 6 7 8 2 4 9
66
3.4 배열을 이용한 희소행렬(4/7) ■ 희소행열을 처리하는 예 1. #include <stdio.h>
2. int s_value[11][3]; 3. int sparse[8][8] = { { 0, 0, 6, 0, 0, 0, 10, 0 }, 4. {31, 0, 0, 0, 0, 0, 0, 0 }, 5. { 0, 0, 0,14, 0, 0, 0, 0 }, 6. { 0,15, 0, 0, 0, 0, 27, 0 }, 7. { 0, 0, 0,31, 0, 0, 0, 0 }, 8. { 0, 0, 0, 0, 0, 0, 0, 0 }, 9. { 0, 0, 0, 0, 0, 3, 0, 0 }, 10. { 0, 0, 1, 0, 0, 0, 35, 0 }}; 11. 12. 13. 14. head() 15. { 16. printf(" \t\t\t\t Sparse Matrix \n\n"); (계속)
67
3.4 배열을 이용한 희소행렬(5/7) ■ 희소행열을 처리하는 예
17. printf(" \t 0col\t 1col\t 2col\t 3col\t"); 18. printf(" 4col\t 5col\t 6col\t 7col\n"); 19. } 20. 21. process(i, j, k) 22. int i, j, k; 23. { 24. for (i = 0; i < 8; i++) { 25. printf(" %3drow\t", i); 26. for (j = 0; j < 8; j++) { 27. if (sparse[i][j] != 0) { 28. k++; 29. s_value[k][0] = i; 30. s_value[k][1] = j; 31. s_value[k][2] = sparse[i][j]; 32. } (계속)
68
3.4 배열을 이용한 희소행렬(6/7) ■ 희소행열을 처리하는 예
33. printf(" %3d\t ", sparse[i][j]); 34. } 35. putchar('\n'); 36. } 37. return(k); 38. } 39. 40. write(k2) 41. int k2; 42. { 43. int i = 8, j = 8; 44. s_value[0][0] = i - 1; 45. s_value[0][1] = j - 1; 46. s_value[0][2] = k2; 47. printf("\n\n\n\t\t\t\t 0col 1col 2col\n"); 48. for (i = 0; i <= s_value[0][2]; i++) (계속)
69
3.4 배열을 이용한 희소행렬(7/7) ■ 희소행열을 처리하는 예
49. printf("\t\t\t %3drow %3d %3d %3d \n", \ 50. i, s_value[i][0], s_value[i][1], s_value[i][2]); 51. } 52. 53. 54. void main() 55. { 56. int i=0, j=0, k = 0; 57. int k1; 58. clrscr(); 59. head(); 60. k1 = process(i, j, k); 61. write(k1); 62. }
Similar presentations