웹사이트 검색

Linux C 프로그래밍 자습서 21부: 문자 포인터, 포인터 배열 및 포인터에 대한 포인터


이 페이지에서

  1. C의 문자 포인터, 포인터 배열 및 포인터에 대한 포인터\n
  2. 결론

포인터의 개념은 실제로 C 프로그래밍 언어에서 매우 중요한 개념 중 하나입니다. 지금까지 우리는 C에서 포인터의 여러 측면에 대해 논의했습니다. 이 자습서에서는 이를 확장하여 몇 가지 포인터 개념에 대해 더 논의할 것입니다.

C의 문자 포인터, 포인터 배열 및 포인터에 대한 포인터

다음 코드 줄을 사용하여 문자 포인터로 시작하겠습니다.

char p[] = "I like HowtoForge"
char *p = "I like HowToForge"

첫 번째 줄은 큰따옴표로 묶인 문자 수와 같은 크기의 배열 p를 정의합니다. 그러나 다음 줄은 문자열 상수를 가리키는 포인터 p를 정의합니다.

여기서 차이점은 첫 번째 p가 배열이므로 배열의 내용을 쉽게 수정하거나 변경할 수 있다는 것입니다. 그러나 두 번째 p가 문자열 상수를 가리키고 있기 때문에 문자열 내용을 변경할 수 없습니다.

예를 들어 다음 코드는 문자열 상수를 수정하려고 시도합니다.

#include <stdio.h>

int main()
{
char *p = "I like HowToForge";

p[0] = 'U';

return 0;
}

그리고 내 시스템에서 이 코드에 의해 생성된 출력은 다음과 같습니다.

Segmentation fault

이 오류는 프로그램 실행이 갑자기 종료되었음을 나타냅니다. 이는 우리가 일정한 것을 변경하려고 시도했기 때문입니다.

또한 포인터 p가 다른 문자열을 가리키도록 만들 수는 있지만 배열 p의 기본 주소를 변경할 수는 없습니다(기억한다면 이전 자습서 중 하나에서 이미 논의했습니다).

이제 정수, 문자 및 다른 유형의 배열을 본 것처럼 포인터 배열로 이동하면 포인터 배열도 있을 수 있습니다. 예를 들어, 다음 프로그램은 정수 포인터의 배열 arr을 정의하고 여기에 값을 할당합니다.

#include <stdio.h>

int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;

arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

return 0;
}

어레이에 할당된 값은 주소입니다. 이는 arr이 포인터의 배열이고 포인터는 주소만 저장하기 때문입니다. 이제 이 주소에 보관된 값에 액세스하려면 *연산자를 사용해야 합니다.

다음 예제(이전 예제의 확장에 불과함)는 이를 보여줍니다.

#include <stdio.h>

int main()
{
int *arr[3];
int a = 0, b = 1, c = 2;

arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

for(int i=0; i < 3; i++)
printf("\n arr[%d] is: %d",i,*(arr[i]));

return 0;
}

결과는 다음과 같습니다.

arr[0] is: 0 
arr[1] is: 1
arr[2] is: 2

정수 포인터 배열(여기서 논의한 것과 같은)과 유사하게 문자 포인터 등을 저장하는 배열을 가질 수 있습니다.

이제 포인터에 대한 포인터로 이동하겠습니다. 지금까지 여러 번 반복했듯이 포인터는 주소를 저장합니다. 지금까지 이 진행 중인 C 프로그래밍 자습서 시리즈에서 포인터가 아닌 변수를 가리키는 포인터만 보았지만 사실 포인터는 다른 포인터도 가리킬 수 있습니다.

이것은 포인터가 다른 포인터의 주소를 저장할 수 있음을 의미합니다. 예를 들어 다음은 이중 포인터 또는 포인터에 대한 포인터입니다.

int **ptr;

다음은 이중 포인터를 사용하는 코드입니다.

#include <stdio.h>

int main()
{
int *ptr;
int **p;

int a = 10;

ptr = &a;

p = &ptr;

printf("\n Pointer 'p' points to pointer 'ptr' which further points to value: %d", **p);

return 0;
}

결과는 다음과 같습니다.

Pointer 'p' points to pointer 'ptr' which further points to value: 10

이것은 이중 포인터의 예였습니다. 유사한 줄에서 예를 들어 int ***ptr로 정의된 포인터에 대한 포인터에 대한 포인터를 가질 수 있습니다. 레벨에 대한 포인터에 대한 이러한 포인터의 최대 수는 구현에 따라 다릅니다(어떤 경우에는 제한이 12입니다).

그러나 실질적으로 레벨 3까지의 포인터에 대한 포인터만 접하게 될 가능성이 높습니다. 레벨이 많을수록 논리를 이해하고 유지하기가 더 복잡해지기 때문입니다.

결론

여기에서 세 가지 중요한 포인터 관련 개념에 대해 논의했습니다. 이러한 작업이 어떻게 작동하는지 더 잘 이해하려면 여기에서 논의한 예제와 개념을 시스템에서 시도하는 것이 좋습니다. 의심이나 질문이 있는 경우 아래에 의견을 남겨주세요.