[질문] 포인터상수에 대한 궁금증 입니다 ~???

cjynim의 이미지

안녕하세요 C를 공부하고 있는 학생입니다... 포인터를 공부하다가 이상한 점이 있어서 질문을 올립니다.

보통 int a = 10; 이라고 하면

printf("%d", a) -> 10이 출력되고
printf("%p", &a) -> a 변수의 주소 값이 출력 되잖아여 ~

그러면 아래는 제가 실험해본 코딩인데여 ~

#include

int main(void) {
int arr[4] = {1, 2, 3, 4};

printf("&arr = %p\n", &arr); // 0012FF54
printf("arr = %p\n", arr); // 0012FF54
printf("&arr[0] = %p\n", &arr[0]); // 0012FF54

return 0;
}

보시는 봐와 같이 &arr, arr, &arr[0] 모두 같은 주소 값을 출력 합니다...

우선 arr와 &arr[0]은 이해가 갑니다. arr는 포인터 상수이기 때문에 arr의 시작 주소 값을 반환하고

&arr[0]은 당연히 0번째 요소의 시작주소니까 arr 포인터 상수와 값이 같게 나오겠죠??

그런데 이상한 것은 &arr 이 부분입니다... 제 생각에는 arr는 단지 포인터 상수로써 배열을 가리키는

역할만 하는 것으로 알고 있습니다. 그러면 이 상수또한 어떠한 메모리 공간에 할당되어 있을텐고 그렇

다면 그 메모리 공간의 주소 값이 나와야 하는것 아닌가요?? 제가 뭔가 잘 못 알고 있는건가요??

Kroisse의 이미지

배열 이름은 포인터 상수가 아닙니다만...

cjynim의 이미지

배열 이름은 포인터 상수가 맞습니다... 만약 배열 이름이 그냥 포인터 라면 배열 이름에 다른

주소를 저장할 수 있지만 배열이름에는 어떠한 다른 주소도 입력이 불가능하며 제가 여러 책을

봤지만 모든 책에 배열 이름은 포인터 상수 또는 상수 포인터라고 명시되어 있습니다 ...

winner의 이미지

불매운동이라도 할까요?
제 생각에 그러한 관점이 배열과 pointer 의 좀더 분명한 이해를 위한 중간과정이라고는 여겨집니다만
저는 그런 식으로 서술한 책은 본 적이 없습니다.

gamdora의 이미지

음······.

sizeof(array) != sizeof(pointer)이기 때문인가요?

cjynim의 이미지

Teach Yourself C의 227쪽에 보면 배열의 이름이 포인터 상수라는 내용이 나옵니다 ...

그리고 열혈강의 C의 307쪽에 나와 있습니다 ...

winner의 이미지

솔직히 저는 그리 경험이 많지 않기 때문에 그런 해석의 해악을 명확히 짚지는 못합니다.
어쩌면 pratice 에서 요구되는 해석수준은 그정도일 뿐일지도 모르지만...

다른 단서없이 그런 식으로만 정의하고 있다면 책의 진수의 깊이에 다시 생각하게 합니다.

열혈강의 C 는 대학후배들이 교재로 공부하는 책인데 그렇게 두껍지 않고,
잘 정리된 Power Point 강의문서, 그리고 열혈강의 series 의 동영상강의에 대해서
훌륭하다는 소리를 들어왔습니다만... 약간 실망을 하게 됩니다.

Teach Yourself C 는 저와 그다지 인연이 없었는데 이런 식으로 마주하는 것이 아쉽군요.

죠커의 이미지

이 책은 일반화되지 못한 설명과 잘못된 설명으로 나열되어 있습니다. 그래서 저는 예전부터 이 책의 해악이 심하다고 판단하여 사용하지 말 것을 권하여 왔습니다. 그러나 여전히 이 책이 인기가 높다는 사실이 슬픕니다.

Teach yourself는 전 입문기에 접했지만 다시 볼 가치가 없다고 생각하여 다 버렸습니다.

- CN의 낙서장 / HanIRC:#CN

ydhoney의 이미지

열혈강의 시리즈 모두가 그런것은 아니고 C만 그렇습니다.

개인적으로 열혈강의 파이썬 시리즈는 상당히 잘 보고 있습니다. :-) (뭐 그 분께서 쓰셨으니까요 ^^)
 
 
====================여기부터 식은어치====================
안녕하세요. 저는 야동 초등학교 2학년 6반 11번입니다!! 제 컴퓨터에 리눅스를 깔아보고 싶습니다. 리눅스라는건 어제 처음 들어 보았습니다.
리눅스에서도 카트라이더는 되겠지요? 설마 안되나요? 안되면 왜 쓰나요? =3=33 리눅스에서는 카트라이더 캐릭터 머리가 너무 커서 못받아들이나요?

익명사용자의 이미지

cmoh1110의 이미지

요부분이 더 문제에 가까운 답일 듯 합니다.

http://www.cinsk.org/cfaqs/html/node8.html#6.12

---------------------

seank76의 이미지

확실히 배열 함수 a는 a = &a 가 맞습니다.

이건 C언어자체에서 그렇게 지정한거고요, 제가 들어본 이유중 가장 설득력있는건 scanf 때문이란겁니다.

int a,b,c;
int d[100];

scanf("값=", &a, &b, &c, &d);

위의 문항이 잘못된건 다 아시겠죠. (&d가 아니고 그냥 d라고 써야겠죠.)
근데 많은 사람들이 &d를 선호했답니다.
그래서 배열 함수의 주소는 그 배열의 제일 첫 요소의 주소로 아예 정해버렸다는군요.

믿거나... 말거나입니다...^^

winner의 이미지

제가 아는 바가 틀리지 않다면

&d 은 일차원 배열의 주소입니다.
이차원배열을 떠올려 보세요.

ab[30][30] 이 있다면
ab[30] 은?...
&ab[30] 은?...

seank76의 이미지

.

익명사용자의 이미지

^^ 그런게 있었군요. 그런데 생각해보면 그렇게 예외를 둘만하죠. 배열이란 주소가 가변한 포인터가 아닙니다. 그런데 그걸 배열의 주소가 아니라 그 포인터 값을 제공한다면 시스템 오류를 유발 하겠죠. 그리고 그 값은 어디에도 쓸모없는 값입니다. 그걸 확인해 보실려고 하신것도 특이하시고 ^^
그렇게 예외를 두고 있군요. 새로운 사실을 알았네요.

swiri15의 이미지

arr과 &arr 이 출력하는 메모리주소는 분명 같습니다만,

그 의미에는 미묘한 차이가 있습니다.

익히 아시고 계신 것처럼 arr은 &arr[0] 과 같은 의미이며, 그 data type은 배열의 data type입니다.

즉 arr + 1의 의미는 arr[0]에서 int형의 size만큼, 4byte 이동한 주소, &arr[1]을 의미할 수 있습니다

하지만 &arr은 그렇지 않습니다. &arr은 arr이라는 이름의 int형 4개짜리 일차원 배열의 시작주소입니다.

이것은 즉 (&arr) + 1 이 &arr[1] 을 의미하지 않음을 말합니다.

이러한 맥락에서 (&arr) + 1은 arr[0]에서 int형의 size*배열의 데이터 갯수(4) 를 곱한만큼 이동한 곳

의 주소입니다. 다음의 코드를 봐주세요.

int a[4] = {0, 1, 2, 3};
int (*pa)[4] = &a; /* 그냥 a를 쓰면 에러가 납니다 &a[0]과 &a는 의미하는 바가 달라서입니다
pa는 int형의 데이터 4개를 가지는 일차원배열을 가리키는 포인터입니다 */
pa++; /* 메모리 주소가 sizeof(int) * 4(배열데이터갯수) 만큼 이동합니다 */
printf("%d\n", (*pa)[-1]); /* pa가 가리키는 일차원 배열을 참조한 후 -1 인덱스,
즉 이는 a[3]을 의미합니다 */

출력되는 값은 물론 3입니다 :)

PS) int (*pa)[4]; /* 위에 나온대로 일차원배열을 가리키는 포인터를 선언합니다 */
int *pa[4]; /* int형의 포인터 4개를 가지는 일차원배열을 선언합니다 */

seank76의 이미지

sizeof 때 의미가 달라지겠네요.
이에 생각보다 유용하겠는데요,
좋은 정보 감사합니다.^^

전웅의 이미지

제가 허접하나마 책을 낸 이후 달라진 점이라면 같은 분야의 다른 책에
대한 비판을 예전만큼 자유롭게 하지 못한다는 점입니다. (회사 일 때문에
바쁘다는 핑계로 수개월째 고장난 서버를 버려두고 있긴 하지만) 제
홈페이지의 과거 게시물들을 보면 예전에는 나름대로 여러 C 언어 책에
대한 비판을 서슴없이 했으나, 책을 낸 이후부터는 한편으로는 책을
낸다는 것 자체가 매우 힘든 일임을 이해하기에, 다른 한편으로는 경솔한
제 비판이 자칫 제 책을 광고하기 위한 수단으로 오해될 수 있기에 다른
책에 대한 평을 자제하고 있습니다.

위에서 CN 님이 지적하신 것처럼 잘못된 내용을 담고 있는 것은 확실
하지만 초보자들을 타깃으로 내용을 쉽게 전달해 C 언어의 진입 장벽을
낮추는데 일조를 했다는 점은 인정하지 않을 수 없습니다. 또한, 워낙에
어려울 수 있는 C 언어의 다양한 개념을 쉽게 설명하기 위해서 오해의
소지가 불가피한 약간의 거짓말과 비유를 드는 것이 효과적일 수 있다는
사실에도 찬성합니다.

하지만 (책에 대한 직접적 비판을 피하기 위해) 약간의 책임을 독자들에게
돌리자면 입문서는 말 그대로 입문서입니다. 긍정적으로 생각하면 (저자의
무지 때문이 아니라) 독자의 이해를 위해 의도적으로 거짓말을 한 부분도
있을 수 있습니다 - 자주 드는 비유입니다만, 수학에 갓 입문해 아직
음수도 배우지 않은 사람에게 실수와 허수를 이야기하는 것은 수학에 대한
거부감만 불러 일으킬 수 있습니다. 따라서 입문서의 내용이 C 언어 이해
의 절대적 권위를 갖는 것으로 오해해서는 안 됩니다.

포인터 상수, 상수 포인터와 배열에 대한 이야기는 이곳이든 뉴스그룹이든
꾸준히 올라오는 주제입니다 (따라서 FAQ 에도 나와 있겠지요). 그만큼
초보자에게 배열-포인터의 관계를 설명하기 위해 자주 사용되는 개념
이라는 뜻이 됩니다. 하지만, "개념"상 이 둘의 차이는 분명히 존재하며
(http://kldp.org/node/75815 도 참고하시기 바랍니다) 따라서 처음에는
배열-포인터 관계의 혼란을 정리해보고자 포인터 상수 등의 개념을 통해
이해했더라도 어느 정도 익숙해진 이후에는 반드시 이 둘을 분리해 구분
하는 것이 필요합니다. 그렇지 않고서는 보다 복잡한 단계로 나아가는데
어려움을 겪을 것입니다.

또 한가지 강조하고 싶은 사실은

    int a[10] = { 0, };
    printf("%p\n", (void *)a);
    printf("%p\n", (void *)&a);

의 두 출력 결과는 같다고 보장되지 않습니다. 이는 이 둘의 주소가 다를
수 있다는 뜻이 아니라 포인터가 주소 이외의 정보 (예를 들면, 가리키는
대상의 크기) 도 포함할 수 있으며, 그 정보가 %p 에 함께 출력될 수
있다는 의미입니다.

그럼...

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.