inflearn logo
강의

Khóa học

Chia sẻ kiến thức

(2026 Mới nhất!) Đỗ thực hành Kỹ sư xử lý thông tin chỉ trong một tuần

Thao tác con trỏ và dạng bài thường gặp (2. Tăng/giảm con trỏ, con trỏ kép)

13분 40초

Đã giải quyết

47

Dann

2 câu hỏi đã được viết

0

char str2[] = "World";
*ptr_b = str2;
printf("%c\n", ptr_a[1]);

이부분은 이해가 계속 안되고 있어서 질문을 드립니다.

앞에서 **ptr_b = &ptr_a;를 했기 때문에
ptr_b가 가지고 있는 값은 ptr_a의 주소입니다. 그래서 만약 ptr_a의 주소가 30000이면 ptr_b의 값은 30000이 저장되고 즉, ptr_b가 ptr_a를 가리키게 되는 것입니다.

그 상태에서

*ptr_b = str2;를 하게되면 ptr_b가 가르키는 주소는 ptr_a이고 그 값은 기존 'H'가 있는 1001이 저장되어 있었지만 갱신되어서 'W'의 주소값이 ptr_a에 저장된다고 이해를 했습니다.

근데 어떻게 *ptr_b = str2;를 했는데 *ptr_b의 값인 30000이 'W'의 주소값으로 바뀌는게 아니고 ptr_b가 가리키고 있는 주소인 ptr_a의 값인 'H'가 'W'로 바뀌는 것입니까?

그리고 *ptr_b = str2; 말고
ptr_b = str2;과 **ptr_b = str2;도 해봤는데 에러가 나던데 그 이유는 무엇입니까?

c 정보처리기사

Câu trả lời 2

0

weekendcode

안녕하세요. 이 부분 많이 헷갈려하시는데, 질문을 보니 거의 다 이해하셨고 딱 한 군데만 잡으면 됩니다.


처음에 이해하신 "ptr_a에 'W'의 주소가 저장된다"는 맞습니다. 헷갈린 곳은 뒤에 쓰신 "*ptr_b의 값인 30000"입니다. 30000은 ptr_b의 값이고, *ptr_b의 값은 30000번지에 들어 있는 내용(1001)입니다. 이 차이 때문에 뒤쪽 이해가 꼬인 겁니다.


주소를 임의로 정해서 같이 따라가 보겠습니다.

str : 주소 1001~1006, 저장된 값 "Hello\0"
str2 : 주소 2001~2006, 저장된 값 "World\0"
ptr_a : 주소 30000, 저장된 값 1001
ptr_b : 주소 40000, 저장된 값 30000


1. *를 몇 개 붙였는지부터 보세요.

ptr_b     // 40000번지에 든 값 = 30000        (타입: char**)
*ptr_b    // 30000번지로 가서 본 값 = 1001    (타입: char*, 곧 ptr_a 자체)
**ptr_b   // 1001번지로 가서 본 값 = 'H'      (타입: char, 곧 str[0])

*를 하나 붙일 때마다 "저장된 주소로 한 번 찾아간다"고 기억하시면 됩니다. 그래서 *ptr_b는 숫자 30000이 아니라, 30000번지에 있는 변수 ptr_a 자체를 뜻합니다. 시험에서는 *ptr_b가 나오면 바로 ptr_a로 바꿔 읽으시면 편합니다.


2. *ptr_b = str2;는 ptr_a = str2;와 같습니다.

대입문 왼쪽에 *ptr_b가 있으면 "30000번지에 값을 써라"라는 뜻입니다. 오른쪽 str2는 배열 이름이니까 첫 원소 주소인 2001이 됩니다.

ptr_a : 주소 30000, 저장된 값 1001 → 2001
ptr_b : 주소 40000, 저장된 값 30000 (그대로)

ptr_b의 값 30000 자체를 바꾸려면 * 없이 ptr_b = ...로 써야 합니다. *를 붙였으니 ptr_b 본인이 아니라 ptr_b가 가리키는 ptr_a가 바뀐 겁니다.

그리고 하나 더 말씀드리면, 'H'가 'W'로 바뀐 것은 아닙니다. str은 여전히 "Hello" 그대로이고, 바뀐 건 ptr_a에 들어 있던 주소(1001 → 2001)입니다. ptr_a가 다른 문자열을 가리키게 된 것뿐입니다.


3. 그래서 ptr_a[1]은 'o'입니다.

ptr_a[1]은 *(ptr_a + 1)과 같습니다. 2001 + 1 = 2002번지 문자를 읽으니까 "World"의 두 번째 글자 'o'가 출력됩니다.


4. ptr_b = str2;와 **ptr_b = str2;가 에러인 이유

둘 다 양쪽 타입이 안 맞아서 그렇습니다. str2는 char*, 즉 문자의 주소입니다.

ptr_b   = str2;   // char** 자리에 char* → 타입 불일치
*ptr_b  = str2;   // char*  자리에 char* → 일치, 정상
**ptr_b = str2;   // char   자리에 char* → 타입 불일치

ptr_b = str2;는 "포인터의 주소"를 담아야 하는 변수에 "문자의 주소"를 넣은 겁니다.

억지로 넣으면 ptr_b가 'W'가 있는 곳을 포인터 변수로 착각하고 읽게 됩니다.

**ptr_b = str2;는 문자 한 칸('H' 자리, 1바이트)에 주소값을 넣으려는 겁니다. 문자 칸에 주소는 들어갈 수 없으니 에러가 납니다.


참고로 C에서는 컴파일러 버전에 따라 이 두 줄이 경고로만 뜨는 경우도 있고, 최근 GCC(14 이상)나 C++에서는 에러로 처리됩니다. 어느 쪽이든 잘못된 코드라고 보시면 됩니다.


실기에서는 이중 포인터 문제가 나오면 위처럼 주소표를 직접 그려놓고 * 하나에 한 칸씩 따라가시면 실수가 확 줄어듭니다. 또 막히는 부분 있으면 편하게 질문 남겨주세요.

0

communityai8509

안녕하세요, 인프런 AI 인턴입니다. Dann님.

질문하신 내용은 char **ptr_b = &ptr_a; 상태에서 이중 포인터를 역참조하는 과정과 관련되어 있습니다.

예를 들어 다음과 같이 선언되어 있다고 가정하겠습니다.

char str[] = "Hello";
char *ptr_a = str;
char **ptr_b = &ptr_a;

char str2[] = "World";
*ptr_b = str2;

각 변수의 관계는 다음과 같습니다.

ptr_a  : str의 시작 주소
ptr_b  : ptr_a의 주소
*ptr_b : ptr_a의 값, 즉 str의 시작 주소

따라서 *ptr_b = str2;는 다음과 같은 의미입니다.

ptr_a = str2;

즉, *ptr_b가 가지고 있던 값인 str의 주소가 str2의 시작 주소로 변경되고, 결과적으로 ptr_a가 "World"를 가리키게 됩니다.

중요한 점은 "H" 자체가 "W"로 바뀌는 것이 아니라는 것입니다.

printf("%c\n", ptr_a[1]);

실행 시 ptr_a가 이제 str2를 가리키므로 ptr_a[1]은 "World"의 두 번째 문자 'o'를 출력합니다. 기존 str 배열의 "Hello"가 "World"로 수정되는 것은 아닙니다. 단지 ptr_a가 가리키는 대상이 str에서 str2로 변경된 것입니다.

각 표현식의 타입도 함께 보면 이해하기 쉽습니다.

ptr_b       // char **
*ptr_b      // char *
**ptr_b     // char

따라서 대입은 다음처럼 타입이 맞아야 합니다.

*ptr_b = str2;    // char* = char*  → 정상

반면 다음 코드는 타입이 맞지 않습니다.

ptr_b = str2;

ptr_b는 char ** 타입인데 str2는 배열 이름이므로 char *로 변환됩니다. 즉, char ** 변수에 char * 값을 대입하려 하므로 타입이 맞지 않습니다.

**ptr_b = str2;

**ptr_b는 char 타입입니다. 반면 str2는 char * 타입이므로 문자 변수에 주소를 대입하려는 형태가 되어 오류가 발생합니다. 특정 문자를 바꾸려면 다음처럼 문자 하나를 대입해야 합니다.

**ptr_b = 'W';

다만 이 경우 ptr_a가 str2를 가리키고 있다면 str2[0]이 'W'로 변경됩니다.

관련하여 이중 포인터에서 역참조할 때 값이 주소가 될 수 있는 이유는 아래 기존 답변에서 단계별로 설명하고 있습니다.

이 답변에서는 ptr_b가 char **, *ptr_b가 char *, **ptr_b가 char가 되는 과정을 설명하고 있어 질문하신 코드의 동작을 이해하는 데 도움이 됩니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

6분46초

0

25

2

공략법

0

24

1

모의고사 파일과 이론파일 업데이트

0

53

2

이론 pdf 다운은 어디서 하나요?

0

48

2

정보처리기사 26년 실기 2회 네트워크 부분

0

58

2

기출문제 재탕

0

51

1

뻬먹은 코드

0

38

1

기출문제 재탕

0

31

0

모의고사1회 2번문제 뭔지 모르겠네요 강의올려주시면안될까요?

0

41

1

영상 다운로드는 안되나요?

0

70

1

26년2회 실기기출은 언제쯤...

0

117

2

이론 공부법 요약본 버전 업데이트 문의

0

91

2

정처기 필기 준비할때 이 이론을 다시 외워도 될까요?

0

105

2

조건 반복문 질문: for 문 ?

0

88

1

정처기 26-2회. 9번 질문드립니다!

0

109

1

이론 보면서 질문이 있습니다.

0

95

2

정보처리기사 실기 26년 2회 SRT 스케줄링 문제 단위 질문

0

118

2

유튜브(정보처리기사 실기 | 26년 2회 기출문제 코드 해설)

0

193

2

262 정처기 실기 C언어코딩

0

74

1

정보처리기사 262 실기 Hash(해시) 질문

0

103

2

static 변수 질문입니다.

0

73

2

파이썬 4강 질문입니다.

0

83

2

모의고사 1회 3번문제

0

107

3

41강 30:10

0

79

2