포인터의 고찰.. 명확한 설명과 이해를 시켜주시면 고맙겠습니다.

wmcst의 이미지

제가 밑에 설명하고 있는게 맞는지 궁금합니다. 아무쪼록 C 프로그래밍의 해박한 분이 리플달아주셨으면 감사하겠습니다.

먼저 제가 궁금해하는 것은 다음의 코드입니다.
int main()
{
int a[3][2] = { {1,2}, {3,4}, {5,6} };

printf("a[0] = %d\n", a[0]);
printf("a = %d\n", a);
printf("*a = %d\n", *a);
printf("**a = %d\n", **a);

return 0;
}

실행 화면
a[0] = 1245032
a = 1245032
*a = 1245032
**a = 1
Press any key to continue

여기서 왜 a의 값과 *a의 값이 같냐는 것입니다.
*a는 1이 아니고 a와 같은 값을 출력하게 되는데 이것의 이유를 알려면 배열명은 상수포인터이니까 먼저 상수포인터의 특징을 알아야 할것 같다는 생각이 들어서 다음과 같이 생각을 하게 되었습니다.

@ 상수 포인터의 특징
상수포인터라는 것은 자신의 주소값을 가지지 않는다.
상수포인터의 주소를 출력하면 상수포인터가 가리키는 주소와 같다.

이것을 알게된 후에 저는 위에서 궁금해하던 점을 다음과 같이 이해하였습니다.
먼저 a[0], a[1], a[2]은 각각 &a[0][0], &a[1][0], &a[2][0]과 같다.
그리고 배열명 a는 a[0]을 가리킨다. 하지만 a[0]는 상수포인터이다.

위의 코드에서 배멸명 a의 타입은 int (*ptr)[2]과 같습니다.
이것은 2개 요소를 가지는 배열을 가리키는 포인터입니다.
int (*ptr)[2] = a; 라고 했을때
printf("ptr = %d\n", ptr);
// a[0]라는 상수포인터의 주소를 출력, 상수포인터의 특징에 따라 a[0]의 주소는 a[0]가 가리키는 주소와 같으므로 &a[0][0]이 출력된다.
printf("*ptr = %d\n", *ptr);
// a[0]가 가리키는 주소를 출력, 따라서 &a[0][0]가 출력된다.
printf("**ptr = %d\n", **ptr);
// *ptr은 &a[0][0]이므로 **ptr은 a[0][0]의 값을 출력하게 된다.

과연 이렇게 이해하는게 맞습니까?
상수포인터의 특징을 제 나름대로 위에서 정의해봤는데 저렇게 생각해도 됩니까?
이렇게 이해하는게 틀리다면 어떻게 이해해야 하나요?

글 읽어 주셔서 감사하고요.. 좋은 답변 바랍니다.

추가적으로 또 한가지 궁금한 것은 g++에서는 안되지만 gcc에서는 다음의 코드가 warning이 뜨지만 실행이 되는데
int **dptr = a;
printf("dptr = %d\n", dptr);
printf("*dptr = %d\n", *dptr); // 1이 출력됨
gcc에서 int **dptr = a와 같이 형 변환이 맞지 않는데 이것을 허용하는데 C 프로그래머가 이러한 것은 하지않도록 주의해야하는 것인가요?

pineway의 이미지

그냥 지나가다 댓글 답니다.

a와 *a 와의 차이점은
a+1 , *a + 1 이라고 했을 때 나타나고
각각
a+1 == &a[1][0] 이고
*a+1 == &a[0][1] 입니다

jocha의 이미지

코딩한지 오래되서 가물가물한 포인터를 정리하는중에 비슷한 질문같아서요..
그냥 기록차 적어놓습니다.

a는 2차원배열의 첫번째요소의 주소이고, *a는 a[0]과 같아서 배열의 0번째 행을 나타내므로 해당 주소는 마찬가지로 a, *a, a[0] 모두가 같습니다.
그러나 실제 서로 같다고 할수는 없는것이 각각에 대해서 sizeof를 해보면 a는 배열전체의 요소인 24바이트를, *a와 a[0]은 열이 2개이므로 8바이트를 가리킵니다.

그리고 int **ptr 은 1차원 포인터배열의 변수이므로 2차원배열인 a를 대입하면 형이 틀리다고 warning이 납니다.
옳바르게 하려면 int (*ptr)[2] 라고 2차원 포인터변수를 선언하고 대입하는것이 맞습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.