배열의 이름은 포인터이다.
단, 그 값을 바꿀 수 없는 '상수 형태의 포인터'이다.
#include <stdio.h>
void main()
{
int arr[3] = { 0,1,2 };
printf("배열의 이름 %p\n", arr); // 배열의 이름 == 첫 번째 변수 //배열의 이름 006FFEB0
printf("첫 번째 요소 : %p\n", &arr[0]); // 배열의 이름과 같은 주소값을 띈다. //첫 번째 요소 : 006FFEB0
printf("두 번째 요소 : %p\n", &arr[1]); // 두 번째 요소 : 006FFEB4
printf("세 번째 요소 : %p\n", &arr[2]); // 세 번째 요소 : 006FFEB8
//arr = &arr[i]; // 이 문장은 컴파일 에러를 일으킨다. >>>> 상수여서 불가능하다.
}
배열의 이름은 배열의 시작 주소 값을 의미하며, 그 형태는 저장이 불가능한 상수이다.
1차원 배열이름의 포인터 형과 배열이름을 대상으로 하는 *연산
1차원 배열이름의 포인터 형은 배열의 이름이 가리키는 대상을 기준으로 결정하면 된다.
#include <stdio.h>
void main()
{
int arr1[3] = { 1,2,3 };
double arr2[3] = { 1.1,2.2,3.3 };
printf("%d \t %lf\n", *arr1, *arr2); // 1 1.1
*arr1 += 100;
*arr2 += 120.5;
printf("%d \t %lf\n", arr1[0], arr2[0]); // 101 121.6
}
포인터 연산
int형 포인터를 대상으로 n x sizeof(int)의 크기만큼 증가
double형 포인터를 대상으로 n x sizeof(double)의 크기만큼 증가
.
.
감소의 결과도 이와 같은 방식이며 감소한다.
TYPE형 포인터를 대상으로 n의 크기만큼 값을 증가 및 감소 시, n x sizeof(TYPE)의 크기만큼 주소 값이 증가 및 감소한다.
★중요한 결론★
printf("%d %d %d\n", *(ptr + 0), *(ptr + 1), *(ptr + 2)); // *(ptr+0) == *ptr
printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]);
printf("%d %d %d\n", *(arr + 0), *(arr + 1), *(arr + 2)); // *(arr+0) == *arr
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
네 문장 모두 동일한 결과 값을 출력한다.
arr[i] == *(arr+i) //arr[i]는 *(arr+i)와 같다.
상수 형태의 문자열을 가리키는 포인터
char str1[ ] = "My String" // 배열의 길이는 자동으로 계산 // 변수 형태의 문자열
char* str2[] = "Your String" // 상수라 문자 변경 불가능. // 상수 형태의 문자열
#include <stdio.h>
void main()
{
char str1[] = "My String"; // 변수 형태의 문자열
char* str2 = "Your String"; // 상수 형태의 문자열 // 상수이기 때문에 배열[]을 안씀!
printf("%s %s\n", str1, str2);
str2 = "Our String";
printf("%s %s\n", str1, str2);
str1[0] = 'x'; //문자열 변경 성공
str2[0] = 'x'; //문자열 변경 실패(에러발생)
printf("%s %s\n", str1, str2);
}
포인터 배열
포인터 변수로 이뤄진 배열
int* arr1[20]; // 길이가 20인 int형 포인터 배열 arr1
double* arr2[30]; // 길이가 30인 double형 포인터 배열 arr2
|
|
이렇듯 포인터 배열도 기본 자료형 배열과 별반 다르지 않다.
변수의 자료형을 표시하는 위치에 int나 double 대신 *int와 *double이 올 뿐이다.
문제1)
길이가 5인 int형 배열 arr을 선언하고 이를 1,2,3,4,5로 초기화 한 다음, 이 배열의 첫 번째 요소를 가리키는 포인터 변수 ptr을 선언한다. 그 다음 포인터 변수 ptr에 저장된 값을 증가시키는 형태의 연산을 기반으로 배열 요소에 접근하면서 모든 배열요소의 값을 2씩 증가시키고, 정상적으로 증가가 이뤄졌는지 확인하는 예제를 작성해보자.
#include <stdio.h>
void main()
{
int arr[5] = { 1,2,3,4,5 };
int * ptr = &arr[0]; // &arr[0] = arr // 배열의 첫 번째 변수 == 배열의 이름
int i;
for (i = 0; i < 5; i++)
{
*ptr += 2;
ptr++;
printf("arr[%d] : %d\n", i, arr[i]);
}
}
문제2)
문제1에서는 포인터 변수 ptr에 저장된 값을 변경시켜가면서 배열요소에 접근하라고 하였다.
그런데 이번에는 포인터 변수 ptr에 저장된 값을 변경시키지 않고, ptr을 대상으로 덧셈연산을 하여, 그 결과로 반환되는 주소 값을 통해서 모든 배열요소에 접근하여 값을 2씩 증가시키는 예제를 작성해보자.
#include <stdio.h>
void main()
{
int arr[5] = { 1,2,3,4,5 };
int * ptr = &arr[0];
int i;
for(i=0; i<5; i++)
*(ptr + i) += 2;
for (i = 0; i < 5; i++)
printf("arr[%d] : %d\n", i, arr[i]);
}
문제3)
길이가 5인 int형 배열 arr을 선언하고 이를 1,2,3,4,5로 초기화한 다음, 이 배열의 마지막 요소를 가리키는 포인터 변수 ptr을 선언한다. 그 다음 포인터 변수 ptr에 저장된 값을 감소시키는 형태의 연산을 기반으로 모든 배열요소에 접근하여, 배열에 저장된 모든 정수를 더하여 그 결과를 출력하는 프로그램을 작성해보자.
#include <stdio.h>
void main()
{
int arr[5] = { 1,2,3,4,5 };
int * ptr = &arr[4];
int i;
int total = 0;
for (i = 4; i >= 0; i--) {
total += *ptr--;
printf("arr[%d] : %d\n", i, arr[i]);
}
printf("%d\n", total);
}
'4. 프로그래밍 기초 > 4_2 C' 카테고리의 다른 글
[열혈 C프로그래밍] 다차원 배열 연습문제 (0) | 2018.12.22 |
---|---|
[열혈 C프로그래밍] 포인터와 함수 연습문제 (0) | 2018.12.22 |
[열혈 C프로그래밍] For문 연습문제 (0) | 2018.12.22 |
[열혈 C프로그래밍] if문 연습문제 (0) | 2018.12.20 |
[열혈 C프로그래밍] While문 연습문제 (0) | 2018.12.20 |