C/C++ 학습 · 8 min read · Oct 11, 2025

C/C++ 단계별 학습 - 9페이지

09. 단계별 C/C++ — C 프로그래밍 - 포인터

포인터

| | 1. 메모리에 대하여

  1. 주소 지정 방식
  2. 변수의 주소 찾기
  3. 포인터
  4. 포인터 산술
  5. 포인터와 배열
  6. 포인터와 문자열
  7. 용어집 |

1. 메모리에 대하여

컴퓨터는 데이터를 저장하고 조작하는 기능을 가지고 있습니다. 데이터 저장에는 저장 장치가 필요하며, 이는 데이터를 빠르고 정확하게 혼란 없이 저장하고 검색하는 데 편리합니다. 일반적으로 컴퓨터는 두 가지 저장 방법을 타협해야 합니다.

| | |

SRAM 정적 임의 접근 메모리
DRAM 동적 임의 접근 메모리
EEPROM 전기적으로 지울 수 있는 프로그래머블 읽기 전용 메모리

메모리 칩은 데이터, 명령 및 중간 및 최종 결과를 저장할 수 있습니다. 메모리는 바이트로 구성되어 있으며, 각 바이트는 하나의 정보 문자를 저장할 수 있습니다. 각 메모리 바이트는 고유하게 식별되는 주소 또는 위치 번호를 가지고 있습니다. 메모리의 크기는 킬로바이트(KB), 메가바이트(Mb), 기가바이트 또는 테라바이트(TB)로 측정됩니다.

RAM:
메모리 장치는 정보를 저장하는 저장 위치입니다.
중요한 컴퓨터 자원인 메모리는 C 프로그램에서 변수 선언 후 각 변수에 할당됩니다. 변수의 유형은 각 변수에 할당될 메모리 바이트 수를 결정합니다.

| | |

2. 주소 지정 방식

| | |

위의 그림은 다음 정보를 제공합니다.

| | 1. RAM은 임시 메모리이며 컴퓨터의 일부입니다.

  1. 프로그램의 값을 저장할 수 있습니다.
  2. RAM의 모든 바이트는 주소라고 불리는 고유한 양수 번호로 식별됩니다.
  3. 주소는 거리의 집 번호처럼 숫자로 표시됩니다.
  4. 숫자는 0에서 시작하여 1-2-3 등으로 증가합니다.
  5. 640 KB의 메모리가 있다면 가장 높은 주소는 655,359이고, 1MB의 메모리에서는 1,048,575입니다.
  6. 프로그램이 메모리에 로드될 때 특정 주소 범위를 차지합니다.
  7. 이는 프로그램의 모든 변수와 모든 함수가 특정 주소에서 시작함을 의미합니다. |

3. 변수의 주소 찾기

지난 섹션의 8번 항목은 각 변수/함수가 특정 주소에서 시작한다고 말합니다. 주소는 16진수 형식의 고유한 양수 번호입니다.

변수의 주소를 찾는 것은 & ( 주소 ) 연산자를 통해 간단한 작업입니다.

& ( 주소 ) - 현재 프로그램에서 변수/함수의 주소를 알려줄 수 있습니다.

다음 프로그램은 변수 ‘a’의 주소를 찾는 방법을 보여줍니다.

| | / 58_address.c /
#include
int main()
{
int a = 10;

printf(“\n A의 값은 : %d”, a);
printf(“\n A의 주소는 : %d”, &a);
return 0;
} |

위의 표시된 형식 값을 다음 형식으로 바꿔서 절대 16진수 주소 값을 얻습니다.

0x%x

예.

 printf("\nA의 주소는 : 0x%x", &a);

함수 ‘disp()’의 주소를 찾는 프로그램

| | / 59_address.c /
#include
void disp()
{
printf(“\n안녕하세요“);
printf(“\n어떻게 지내세요“);
printf(“\n당신은“);
} int main()
{
disp();
printf(“\n disp()의 주소 : 0x%x”, &disp);
return 0;
} |

4. 포인터

지난 섹션에 따르면 변수/함수의 주소를 찾고 표시하는 방법을 알고 있습니다.
이번에는 변수/함수의 주소를 다른 변수에 저장하는 방법을 배웁니다.

참고: 변수는 상수 값을 보유할 수 있습니다.

| | 다음으로 시도해 보세요: int a, b;
a = 5;            / 유효 /
b = &a;           / 유효하지 않음 / 다시 다음으로 시도해 보세요: int a, b;
a = 5;            /
유효 /
b = &a;           /
유효 */ |

b = &a; 맞습니다! 예, 변수(일반 변수)는 주소를 보유할 수 없습니다. 그러나 ‘*’로 시작하는 변수(포인터 변수)는 상수 값과 다른 변수/함수의 주소를 모두 보유할 수 있습니다.

포인터: 주소 값을 보유하는 변수.

| | 변수 (일반)
일반 변수는 상수 값을 보유하는 단일 작업만 수행합니다. | 포인터 변수 ( ‘*’로 시작하는 변수)
포인터 변수는 상수 값과 다른 변수/함수의 주소 값을 보유하는 두 가지 작업을 수행할 수 있습니다. |

주소에 대한 참조 / 포인터 / 주소의 내용 (*)

int *ptr;

초보자에게는 다소 기이한 구문입니다. 별표는 포인터를 의미합니다. 따라서 이 문장은 변수 ptrint에 대한 포인터로 정의합니다. 이는 변수가 정수 변수의 주소를 보유할 수 있음을 의미하는 또 다른 방법입니다.

| | 만약 우리가 그것을 포인터 유형이라고 부른다면 선언을 다음과 같이 쓸 수 있습니다.

포인터   ptr;  /*  유효하지 않음 */
``` 문제는 컴파일러가 포인터가 가리키는 변수의 종류를 알아야 한다는 것입니다.  |


|  | 포인터 변수의 선언  
char *cptr;           /* 문자에 대한 포인터 */  
int *iptr;            /* int에 대한 포인터 */  
float *fptr;            /* float에 대한 포인터 */  
struct emp *e;            /* 추상화된 데이터 emp e에 대한 포인터 */ |

#### 포인터가 가리키는 변수에 접근하기:

이름 대신 주소를 사용하여 변수의 값을 접근하는 특별한 방법입니다.


|  | /* 60_addr.c */  
#include   
int main()  
{  
int var1 = 11; /* 변수 var1 = 11 */  
int *ptr; /* 포인터로서의 변수 ptr */  
  
ptr = &var1; /* var1의 주소를 ptr에 저장 */  
  
printf("var1의 값은 %d입니다", *ptr); /* var1의 주소에 대한 포인터 */  
return 0;  
} |


|  | ![](/files/4f55092a-e6b6-422d-af47-d517ba51db5b.jpg) |


만약 문장이 printf("%d", ptr);라면, ptr의 값을 표시하여 var1의 주소를 의미하지만, 위의 문장은 ptr 변수에 저장된 주소의 내용을 표시할 수 있습니다.

주소_의 및 포인터_의 사용을 보여주는 프로그램


|  | /* 61_ptrdemo.c */  
#include   
int main()  
{  
int a = 10, *p; /* 정수 a와 포인터 p */  
p = &a; /* a의 주소를 p에 할당 */  
  
printf("\nA의 값 : %d", a); /* a의 내용 */  
printf("\nA의 주소 : 0x%x", &a); /* a의 주소 */  
printf("\nP의 값 : 0x%x", p); /* p의 내용 */  
printf("\nP의 주소 : 0x%x", &p); /* p의 주소 */  
printf("\n a의 주소의 내용 : %d", *p); /* &a에 대한 포인터 */  
return 0;  
} |


#### 5. 포인터 산술

모든 변수는 산술 연산을 지원할 수 있으며, 포인터에 대해서도 산술 연산을 수행할 수 있습니다. C/C++ 언어는 포인터에 대해 4가지 산술 연산을 지원합니다.


|  | 연산  
덧셈  
뺄셈  
증가  
감소 | 기호  
+  
-  
++  
-- |



참고: 포인터 산술의 주요 특징은 위의 연산자가 변수 유형에 따라 바이트 단위로 작용한다는 것입니다.


|  | /* 62_ptr.c */  
/* 포인터 산술의 시연 */  
#include   
int main()  
{  
int a, *p;  
a = 100;  
p = &a;  
(*p)++; /* 주소의 내용에 1을 증가 */  
printf("%d", *p);  
return 0;  
} |
|  | 출력  
101 |


포인터 산술의 시연, 주소 값을 증가시킴


|  | /* 63_ptr.c */  
/* 주소 값을 1만큼 증가 */  
#include   
int main()  
{  
int a, *p;  
a = 100;  
p = &a;  
*p++; /* p의 주소 값을 1만큼 증가 */  
printf("%d", *p);  
return 0;  
}  |
|  | 출력  
예상치 못한 출력 |


위의 프로그램은 값과 주소 증가에 대한 산술 연산자를 설명합니다. p는 포인터 변수이고 a는 100으로 할당되며, pa의 주소로 할당됩니다.

이제 *p++는 메모리를 2바이트 건너뛰어 새로운 주소와 그 내용을 가져옵니다.

만약 **(*p)++라면, p**가 가리키는 내용인 100이 증가하여 101이 됩니다.

#### 6. 포인터와 배열

C/C++ 언어에서 데이터 유형 포인터와 배열은 서로 유사합니다. 배열 요소 참조와 포인터 변수 모두 메모리에서 데이터 요소의 주소를 보유하는 데 사용됩니다.


|  | char name[20];  
또는  
char *name ;  
  
char months[12][10];  
또는  
char **months; |


포인터와 배열 간에는 밀접한 연관이 있습니다. 배열에 대한 리뷰는 다음과 같습니다.


|  | /* 64_ptrarr.c */  
#include   
int main()  
{  
int i, a[5] = { 56, 43, 78, 98, 12 };  
for( i = 0; i < 5; i++)  
printf("\n%d", a[i]);  
return 0;  
} |


포인터 표기법을 사용하여 배열 요소에 접근할 수 있는 가능성이 있습니다.  
다음 프로그램의 출력을 찾으세요.


|  | /* 65_ptrarr.c */  
#include   
int main()  
{  
int i, a[5] = { 56, 43, 78, 98, 12 };  
for( i = 0; i < 5; i++)  
printf("\n%d", *(a + i) );  
return 0;  
} |


다음 프로그램을 따르세요:


|  | /* 66_ptrarr.c */  
#include   
int main()  
{  
int i, a[] = { 56, 43, 78, 98, 12 }, *p;  
p = a;  
for( i = 0; i < 5; i++)  
printf("\n%d", *(p + i) );  
return 0;  
} |


주어진 배열의 요소를 인쇄하는 가장 쉬운 방법입니다(크기 필요 없음).


|  | /* 67_ptrarr.c */  
#include   
int main()  
{  
int i, a[] = { 56, 43, 78, 98, 12 }, *p;  
p = a;  
while (*p)           /* 또는 for(int i = 0; i<5; i++ ) */  
printf("\n%d", *p++);  
return 0;  
} |

#### 7. 포인터와 문자열

문자열은 공백을 포함한 문자 모음입니다. 이번에는 포인터를 사용하여 문자열을 처리하는 방법에 대해 논의합니다. 혼란을 피하기 위해 더 이상 논의하지 않겠습니다. 포인터와 문자열 배열 모두를 확인하는 간단한 작업입니다.

문자열과 포인터 간에는 미세한 차이가 있습니다. 프로그램을 따르세요.


|  | /* 68_ptrstr.c */  
#include   
int main()  
{  
char str1[] = "C를 탐험하고 싶습니다.";  
char *str2 = "C를 탐험하고 싶습니다.";  
puts(str1);  
puts(str2);  
str1++; /* 유효하지 않은 표현 */  
str2++; /* 유효한 표현 */  
puts(str2); /* ou would like to…… 출력 */  
return 0;  
} |


함수 인수로서의 문자열

포인터 변수는 배열 변수보다 더 유연합니다. 다음은 포인터 표기법으로 문자열을 표시하는 프로그램입니다.


|  | /* 69_ptrarr.c */  
#include   
void disp(char *p);  
int main()  
{  
char str[] = "안녕하세요!!..안녕하세요!!.. 포인터가 처리할 수 있나요?";  
disp(str);  
return 0;  
} void disp(char *p)  
{  
while(*p)  
printf("%c", *p++);  
} |


문자열의 포인터 배열

문자열의 배열을 저장하는 데 단점이 있습니다. 문자열을 보유하는 하위 배열은 모두 동일한 길이여야 합니다. 따라서 하위 배열보다 짧은 문자열이 있을 때 공간이 낭비됩니다. 해결책은 다음과 같습니다:


|  | /* 70_strings.c */  
#include   
int main()  
{  
char *weeks[7] = { "일요일", "월요일", "화요일", "수요일",  
"목요일", "금요일", "토요일" };  
int i;  
for( i = 0; i < 7; i++)  
puts(weeks[i]);  
return 0;  
} |


문자열이 배열의 일부가 아닐 때, C/C++는 메모리에 연속적으로 배치하므로 공간이 낭비되지 않습니다.
  
**/* 정수 유형의 포인터 배열을 보유하는 예제 프로그램 */**


|  | /* 71_ptrarr.c */  
#include   
int main()  
{  
int *arr[4]; /* 정수 포인터 배열 */  
int i = 31, j = 5, k = 19, l = 71, m;  
  
arr[0] = &i;  
arr[1] = &j;  
arr[2] = &k;  
arr[3] = &l;  
  
for(m = 0; m <= 3; m++)  
printf("\n%d", *(arr[m]));  
return 0;  
} |


라이브러리 함수에 대한 개요

우리는 이미 표준 문자열 함수에 익숙합니다. 이들은 포인터 표기법을 사용하여 지정된 문자열 인수를 가지고 있습니다.  
포인터와 문자열 개념을 명확히 이해하면, 자신의 문자열 함수를 작성할 수 있습니다.  
다음은 문자열을 복사하는 예제 프로그램입니다.  
  
**/* 포인터로 한 문자열을 다른 문자열로 복사 */**


|  | /* 72_strcpy1.c */  
#include   
void strcpy1(char * dest, char *src);  
  
int main()  
{  
char *str1 = "C/C++에 대해 더 배우려면 어떻게 해야 하나요!!!";  
char *str2;  
strcpy1(str2, str1);  
puts(str2);  
return 0;  
} void strcpy1(char * dest, char *src)  
{  
while(*src)  
*dest++ = *src++;  
*dest = '\0';  
} |


#### 8. 용어집


| 주소 | 메모리의 위치를 가리키는 값. 포인터는 값 자체가 아닌 값의 주소 또는 위치를 포함합니다. |
| 배열 | 배열은 동일한 유형의 데이터 항목 모음입니다. |
| 연속적 | 메모리 또는 디스크에서 값이 연속적인 위치에 저장된다는 것을 지정하는 저장 특성입니다. |
| 함수 | 특정 작업을 수행하기 위한 일련의 명령으로, 다른 함수와 결합하여 프로그램을 생성할 수 있습니다. |
| 메모리 | 데이터를 수용하고 보유하며 나중에 요구 시 제공할 수 있는 장치 또는 매체를 설명합니다. 저장과 동의어입니다. |
| 포인터 | 값 자체가 아닌 값의 주소 또는 메모리 위치를 포함합니다. |
| RAM | (임의 접근 메모리) 1. 데이터 검색에 필요한 시간이 데이터의 물리적 위치에 의해 크게 영향을 받지 않도록 구조화된 저장 장치입니다.  2. 개인 컴퓨터의 *주 저장 섹션*입니다. |
| 문자열 | 0개 이상의 문자를 저장할 수 있는 배열입니다. C에서 문자열은 NULL(\0) 문자가 추가된 문자 배열로 선언됩니다. |
| 변수 | 프로그램 실행 중 값이 변경될 수 있는 메모리 위치와 연결된 이름입니다. |
Share: X/Twitter LinkedIn

새 게시물을 받은 편지함에서 받기

스팸은 없습니다. 언제든지 구독 해지 가능합니다.