C언어) 포인터 - 포인터와 배열

Lapis0875·2022년 10월 19일
0

c언어

목록 보기
3/21
post-thumbnail

📑포인터 시리즈

포인터 5부작 중 3부에요. 지난 2개의 글을 읽었거나, 이미 알고계신게 아니라면 이 시리즈의 지난 글들도 읽어주세요 😉

➡️배열 이름은 사실 포인터에요

포인터를 배우고 나서 돌아보면, 배열 이름은 어떻게 동작하는지 궁금해져요. 여러 개의 원소를 가지고 있는데, 어떻게 이 원소들의 값을 가져오고 변경할 수 있는걸까요?

사실, 배열 이름은 배열의 첫 번째 원소를 가리키는 상수 포인터에요.

int array[3] = {1, 2, 3}, *p;
p = array;		// p = &array[0];

printf("array[2] = %d\n", *(array + 2));
printf("*(p + 1) = %d\n", p[1]); 

*(array + 2) 처럼, 포인터 연산을 사용할 수 있어요. 이는 array[2] 와 같아요.
반대로, 포인터 변수 p도 배열처럼 인덱스를 사용할 수 있어요.
p[1]*(p + 1) 과 같아요.

하지만, 배열 이름은 상수 포인터라 기존 포인터와는 조금 달라요. 배열 이름은 배열의 첫 번째 원소를 가리키는 고정된 포인터라, 다른 주소를 가리킬 수 없어요.

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

// 배열 이름의 주소는 변경할 수 없어요.
a = &i;
a++;
a = a + 1;

2차원 배열의 경우도 똑같이 다룰 수 있어요.
2차원 배열에서 인덱스 하나를 제거하면 포인터가 돼요.

int two[2][2] = {1, 2, 3, 4};
int *p = two[1];	// int *p = &two[1][0]

// two[1][1] == *(two[1] + 1)
printf("two[1][1] = %d\n", *(two[1] + 1));

2차원 배열에서 인덱스를 두 개 제거하면, 배열 포인터가 돼요.

int b[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int (*p)[3] = b;		// p는 int[3]을 가리키는 포인터 변수에요.

printf("b[0][1] = %d\n", *( *b + 1 ) );
printf("b[1][0] = %d\n", *( *( p + 1) ) );
printf("b[2][2] = %d\n", *( *( p + 2 ) + 2) );

💡배열과 함수

배열 이름이 포인터라는 건, 함수의 인자로 배열을 받을 때도 포인터로 받는다는 뜻이에요.
아래의 sum함수는 배열 s와 배열의 크기 size를 받아, 배열 내 원소들의 합을 반환해요.

int sum(int s[], int size)
{
	int sum = 0, i;
	for (i = 0; i < size; i++)
    	sum += s[i];
    return sum;
}

배열 s는 포인터로도 받을 수 있어요.

int sum_p(int *s, int size)
{
	int sum, i;
    for (i = 0; i < size; i++)
    	sum += *(s + i);
    return sum;
}

배열을 매개 변수로 받는 함수를 호출 할 때, 주소 값을 전달하면 돼요.

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

total = sum(a, 5);
// total = a[0] + a[1] + ... + a[4]

total = sum(&a[2], 3);
// total = a[2] + a[3] + a[4]

total = sum(&i, 1);
// total = i

💬문자열과 포인터

문자열도 문자의 배열이기 때문에, 앞선 예제들처럼 포인터로 다룰 수 있어요.

char *p = "abcde";
char s[] = "abcde";

printf("%c %c %c %c\n", p[0], *p, s[0], *s);
// a a a a
printf("%s %s\n", p, s);
// abcde abcde
printf("%s %s\n", p+2, s+2);
// cde cde

문자 배열과 문자열 포인터는 한가지 차이점을 가져요.

char name[20] = {};
char *name_p;
scanf("%s", name);
scanf("%s", name_p);	// 오류

name은 이미 배열의 0번째 주소 값을 가지고 있는 상수 포인터라 scanf에 배열 이름을 넘겨주면 표준 입력으로부터 값을 받을 수 있어요.
하지만, name_p는 char형의 포인터일 뿐 아직 가리키는 주소가 없어서 scanf에 인자로 넘겨줘도 표준 입력에서 값을 받을 수 없어요.


배운 내용들을 정리해보고 있어요. 잘못 기재된 내용이 있다면, 댓글로 지적해주시면 수정할게요.

profile
새내기 대학생 개발자에요 :D

0개의 댓글