C/C++ 학습 · 8 min read · Oct 11, 2025
C/C++ 단계별 학습 - 9페이지
09. 단계별 C/C++ — C 프로그래밍 - 포인터
포인터
| | 1. 메모리에 대하여
- 주소 지정 방식
- 변수의 주소 찾기
- 포인터
- 포인터 산술
- 포인터와 배열
- 포인터와 문자열
- 용어집 |
1. 메모리에 대하여
컴퓨터는 데이터를 저장하고 조작하는 기능을 가지고 있습니다. 데이터 저장에는 저장 장치가 필요하며, 이는 데이터를 빠르고 정확하게 혼란 없이 저장하고 검색하는 데 편리합니다. 일반적으로 컴퓨터는 두 가지 저장 방법을 타협해야 합니다.
| | |
SRAM 정적 임의 접근 메모리
DRAM 동적 임의 접근 메모리
EEPROM 전기적으로 지울 수 있는 프로그래머블 읽기 전용 메모리
메모리 칩은 데이터, 명령 및 중간 및 최종 결과를 저장할 수 있습니다. 메모리는 바이트로 구성되어 있으며, 각 바이트는 하나의 정보 문자를 저장할 수 있습니다. 각 메모리 바이트는 고유하게 식별되는 주소 또는 위치 번호를 가지고 있습니다. 메모리의 크기는 킬로바이트(KB), 메가바이트(Mb), 기가바이트 또는 테라바이트(TB)로 측정됩니다.
RAM:
메모리 장치는 정보를 저장하는 저장 위치입니다.
중요한 컴퓨터 자원인 메모리는 C 프로그램에서 변수 선언 후 각 변수에 할당됩니다. 변수의 유형은 각 변수에 할당될 메모리 바이트 수를 결정합니다.
| |
|
2. 주소 지정 방식
| |
|
위의 그림은 다음 정보를 제공합니다.
| | 1. RAM은 임시 메모리이며 컴퓨터의 일부입니다.
- 프로그램의 값을 저장할 수 있습니다.
- RAM의 모든 바이트는 주소라고 불리는 고유한 양수 번호로 식별됩니다.
- 주소는 거리의 집 번호처럼 숫자로 표시됩니다.
- 숫자는 0에서 시작하여 1-2-3 등으로 증가합니다.
- 640 KB의 메모리가 있다면 가장 높은 주소는 655,359이고, 1MB의 메모리에서는 1,048,575입니다.
- 프로그램이 메모리에 로드될 때 특정 주소 범위를 차지합니다.
- 이는 프로그램의 모든 변수와 모든 함수가 특정 주소에서 시작함을 의미합니다. |
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;초보자에게는 다소 기이한 구문입니다. 별표는 포인터를 의미합니다. 따라서 이 문장은 변수 ptr을 int에 대한 포인터로 정의합니다. 이는 변수가 정수 변수의 주소를 보유할 수 있음을 의미하는 또 다른 방법입니다.
| | 만약 우리가 그것을 포인터 유형이라고 부른다면 선언을 다음과 같이 쓸 수 있습니다.
포인터 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;
} |
| |  |
만약 문장이 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으로 할당되며, p는 a의 주소로 할당됩니다.
이제 *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) 문자가 추가된 문자 배열로 선언됩니다. |
| 변수 | 프로그램 실행 중 값이 변경될 수 있는 메모리 위치와 연결된 이름입니다. | 새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.