[고급 C++]포인터 2편(배열과 포인터)
- 컴퓨터공학과/Programming
- 2020. 10. 21.
배열과 포인터 |
1차원 배열과 포인터
배열 특성
- 배열의 이름은 배열의 시작주소(num = &num[0] =배열의 시작주소)
- 연속적인 메모리 할당 보장
1 #include <stdio.h> 2 int main() 3 { 4 int num[5] = {100, 200, 300, 400, 500}, i; 5 int *p1; 6 7 printf("%d, %d \n", sizeof(num), sizeof(num[0])); 8 9 printf("\n"); 10 for(i = 0; i < 5; i++) 11 printf("%p: %d \n", &num[i], num[i]); // 연속된 메모리 보장 12 13 return 0; 14 } |
:!a.out 20, 4
7ffff0f4: 200 7ffff0f8: 300 7ffff0fc: 400 7ffff100: 500 |
- 배열은 포인터와 밀접한 관계를 가지며 배열을 포인터 변수를 이용하여 제어 가능
count + i = ptr + i = &count[i] = &ptr[i] : 배열의 i+1번째 위치 주소
*(count + i) = *(ptr + i) = count[i] = ptr[i] : 배열의 i+1번째 위치 데이터
1 #include <stdio.h> 2 int main() 3 { 4 int num[5] = {100, 200, 300, 400, 500}, i; 5 int *p1; 6 7 printf("%d, %d \n", sizeof(num), sizeof(num[0])); 8 printf("%d, %p, %p \n", num[0], &num[0], num); 9 // 첨자가 없는 배열변수는 그 배열이 할당된 메모리의 10 // 시작주소를 갖는 포인터 상수이다. 11 12 p1 = num; 13 printf("\n"); 14 for(i = 0; i < 5; i++) 15 printf("%p: %d, %d, %d, %d %p %d\n", 16 &num[i], num[i], *(p1+i), *p1+i, *(num+i), num+i, p1[i]); 17 // 컴파일 과정에서 대괄호는 전부 포인터식으로 변환 (num[2] → *(num+2)) 18 return 0; 19 }
|
:!a.out 20, 4 100, 7ffff0f0, 7ffff0f0
7ffff0f0: 100, 100, 100, 100 7ffff0f0 100 7ffff0f4: 200, 200, 101, 200 7ffff0f4 200 7ffff0f8: 300, 300, 102, 300 7ffff0f8 300 7ffff0fc: 400, 400, 103, 400 7ffff0fc 400 7ffff100: 500, 500, 104, 500 7ffff100 500 |
* %s : 입력받은 주소부터 ‘\0’까지 문자열로 출력
- 배열을 함수의 인수로 전달해야할 경우 배열은 배열전체가 복사되어 전달되는 것이 아니라 배열 시작 주소만이 전달되므로 배열을 받을 함수의 매개변수는 포인터로 선언되어야 함
* 배열(주소) 뿐만 아니라 배열의 크기도 함께 전달해야 사용 가능
1 #include <stdio.h> 2 3 int main() 4 { 5 int sal[5]={1500,4300,5000,2700,4200}, i; 6 int siz = sizeof(sal)/sizeof(sal[0]); // 배열의 크기(개수) = 전체 배열 크기 / 배열 하나 크기 7 printf("sal : %p %d \n", &sal, sizeof(sal)); 8 9 salCalc(sal, siz); // 배열 전달, 배열의 크기 도 같이 전달해야함 10 11 return 0; 12 } 13 14 // 월급평균을 계산 15 salCalc(int *tmp, int tmpSiz) 16 { 17 int i, salTot=0; 18 19 for(int i=0;i<tmpSiz;i++) 20 { 21 printf("%d ", *(tmp+i)); 22 salTot += *(tmp+i); 23 } 24 25 printf("\n"); 26 printf("월급평균 : %.2f \n", (float)salTot/tmpSiz); 27 } |
:!a.out sal : 7ffff0f0 20 1500 4300 5000 2700 4200 월급평균 : 3540.00 |
* 응용 : 한글자 찍는 문제
- p2 주소가 NULL이면 주소값은 0이 아니므로 while문 종료
while(*p2) |
- 배열명도 배열의 시작주소를 갖는 포인터 상수이기 때문에 포인터연산( *(num+1) )을 통해 배열에 접근할 수 있으나,
- 배열명은 포인터 상수이기 때문에 그 주소의 값을 변경하거나 새로운 주소를 저장할 수 없음. 즉, 주소이지만 constant이므로 배열변수는 증감불가
while(*str) |
에러! |
2차원 배열
형태
- 1차원배열 : a2[열];
- 2차원배열: a3[행][열]; (대괄호 2개)
- 3차원배열 : a4[면][행][열]
특성
- 배열은 포인터와 밀접한 관계를 가지며 배열을 포인터 변수를 이용하여 제어 가능
count[i][j]는 *(*(count+1)+j)과 동일함
&count[i][j] 주소는 *(count+i)+j와 동일함
1 #include <stdio.h> 2 3 int main() 4 { 5 6 int count[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12}, i, j; 7 8 // 배열이름과 첫배열주소는 같음 9 printf("%d %d \n", sizeof(count), sizeof(count[0][0])); 10 printf("%d %p %p \n", count[0][0], &count[0][0], count); 11 12 printf("\n"); 13 for(i=0;i<4;i++) 14 { 15 for(j=0;j<3;j++) 16 printf("%p:%d \t", &count[i][j], count[i][j]); 17 printf("\n"); 18 } 19 20 printf("\n"); 21 for(i=0;i<4;i++) 22 { 23 for(j=0;j<3;j++) 24 printf("%p:%d \t", *(count+i)+j, *(*(count+i)+j)); 25 printf("\n"); 26 } 27 28 return 0; 29 }
|
:!a.out 48 4 1 7ffff0e0 7ffff0e0
7ffff0e0:1 7ffff0e4:2 7ffff0e8:3 7ffff0ec:4 7ffff0f0:5 7ffff0f4:6 7ffff0f8:7 7ffff0fc:8 7ffff100:9 7ffff104:10 7ffff108:11 7ffff10c:12
7ffff0e0:1 7ffff0e4:2 7ffff0e8:3 7ffff0ec:4 7ffff0f0:5 7ffff0f4:6 7ffff0f8:7 7ffff0fc:8 7ffff100:9 7ffff104:10 7ffff108:11 7ffff10c:12
|
- 첨자가 없는 배열변수는 데이터가 아닌 그 배열의 시작주소를 나타내며, 2차원 배열에서 배열 변수명과 첨자를 하나만 사용하는 것은 배열의 행을 의미
- 행은 데이터가 아닌 각 행이 시작되는 메모리의 주소임
6 int count[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12}, i, j; 7 8 // 배열이름과 첫배열주소는 같음 9 printf("%d %d \n", sizeof(count), sizeof(count[0][0])); 10 printf("%d %p %p \n", count[0][0], &count[0][0], count); 11 12 // 행주소 13 printf("%d \n" , sizeof(count[0])); 14 printf("%p %p %p %p \n", 15 count[0], count[1], count[2], count[3]); 16
|
:!a.out 48 4 1 7ffff0e0 7ffff0e0 12 7ffff0e0 7ffff0ec 7ffff0f8 7ffff104 |
다음편에서는 본편에서 익힌 배열을 바탕으로 배열 포인터, 포인터 배열에 대하여 알아보겠습니다.
[고급 C++]C컴파일러와 C라이브러리(공유/정적/동적라이브러리)
[고급 C++]포인터 1편(프로세스/포인터변수/포인터연산/NULL포인터)
궁금한 사항은 댓글로 남겨주세요💃💨💫
좋아요와 구독(로그인X)은 힘이 됩니다 🙈🙉
'컴퓨터공학과 > Programming' 카테고리의 다른 글
[고급 C++]포인터 4편(다중 포인터/함수 포인터/void형 포인터) (1) | 2020.10.23 |
---|---|
[고급 C++]포인터 3편(배열 포인터/포인터 배열/문자열 상수 포인터) (2) | 2020.10.22 |
[고급 C++]포인터 1편(프로세스/포인터변수/포인터연산/NULL포인터) (0) | 2020.10.20 |
[고급 C++]조건 컴파일 / make (0) | 2020.10.19 |
[고급 C++]C컴파일러와 C라이브러리(공유/정적/동적라이브러리) (0) | 2020.10.18 |