C언어 포인터에서.. *(array)[n] 와 *array[n]

yangam의 이미지

*array[n] 은 그림으로써 머리에 그려지는데.
*(array)[n] 은 그림으로써 머리에 그려지지가 않네요.

#include <stdio.h>

int main()
{
    char *string[] = {
			"I know.",
			"pointer :)",
			"wow!"
	   	     };

    int *(num)[3];
    int wow[][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

    num[0] = &wow[0][0];    
    num[1] = &wow[1][0];    
    num[2] = &wow[2][0];    

    printf("string[0] = %s\n", string[0]);
    printf("string[1] = %s\n", string[1]);
    printf("string[2] = %s\n", string[2]);

    puts("");

    printf("num[0][0] = %d\twow[0][0] = %d\n", num[0][0], wow[0][0]);
    printf("num[0][1] = %d\twow[0][1] = %d\n", num[0][1], wow[0][1]);
    printf("num[0][2] = %d\twow[0][2] = %d\n", num[0][2], wow[0][2]);
    printf("num[1][0] = %d\twow[1][0] = %d\n", num[1][0], wow[1][0]);
    printf("num[1][1] = %d\twow[1][1] = %d\n", num[1][1], wow[1][1]);
    printf("num[1][2] = %d\twow[1][2] = %d\n", num[1][2], wow[1][2]);
    printf("num[2][0] = %d\twow[2][0] = %d\n", num[2][0], wow[2][0]);
    printf("num[2][1] = %d\twow[2][1] = %d\n", num[2][1], wow[2][1]);
    printf("num[2][2] = %d\twow[2][2] = %d\n", num[2][2], wow[2][2]);

    return 0;
}

*array[n] 은 포인터를 배열로서 정의한거잖아요?
그래서 n 개의 요소 각각이 포인터.
지금 이건, 머리에도 그려지고 개념은 확실히 이해가 갔거든요.

그런데 *(array)[n] 은.. C 언어 기초 + a 에서 보니까..
'참고' 라고 적혀있으면서 char *x[4] 와 char (*x)[4] 에 대해서 설명하는데요...

(char *x[4] 와 같은 것은 이해가 됐으므로 생략...)
-> char (*x)[4]; 는 "인수선언에서 4개의 char형의 배열로의 포인터" 를 표시한다.

라고 적혀있는데.. 이해가 잘 안가네요.
현재 이해 하기로는 type (*x)[4] 같은 형태의 포인터는
이차원 배열을 가리킬 때 사용하는 것 같은데... (위의 예제에서도 그렇듯이)
사실, 머리에서 그림으로 정확히 그려지지 않으니까 아직도 잘 모르겠네요.

답변 부탁드립니다;;;;

ps1.
num[0] = &wow[0][0]; 이라고 하면 경고가 안뜨는데
num[0] = wow; 라고 하면 경고가 뜨네요.

wow 가 wow[0] 을 가리키고, wow[0] 이 wow[0][0] 을 가리키니까
상관없는거 아닌가요?

참고로 컴파일러는 gcc 3.3.4 입니다.

ps2.
char *string[] = { "a", "b", "c", "ADSFDFDSDSFSD" };

이런 식으로 선언하면 안되는거 아닌가요?
malloc() 같은 것으로 메모리 할당을 해준다음에 사용해야하는거 아닌가요?
원래는 메모리 침범 인데.. 컴파일러가 똑똑해서...
비어있는 메모리를 할당해주는거 아닌가요?

lsj0713의 이미지

*array[n] 와 *(array)[n] 는 같습니다. 아마도 물으시는 것은 (*array)[n] 같군요.

연산자 우선순위는 *와 [] 중에서 []쪽이 더 높습니다. 따라서 *array[]은 []와 먼저 결합한 뒤에 *와 결합하게 됩니다. 이걸 영어로 해석해서 보면...

*array[n] - array of pointer to "type"
(*array)[n] - pointer to array of "type"

전자는 배열, 즉 특정 형을 가리킬 수 있는 포인터형의 배열입니다.
후자는 포인터, 즉 특정 형의 배열을 가리킬 수 있는 포인터입니다.
자세한 것은 다음 페이지를 참고하세요.

http://wiki.kldp.org/wiki.php/CLangaugeComplexDeclaration

ps1의 질문에서...
wow는 배열 이름이므로 자신의 첫번째 원소를 가리키는 포인터 주소값으로 자동 변환됩니다(물론 항상 그런 것은 아니고 몇가지 예외상황이 있습니다). 따라서 wow의 타입은 pointer to array of int가 되는 겁니다. 그러나 num[0]의 타입은 pointer to int죠. 타입 일치가 안되니까 당연히 경고 메시지가 뜨는 겁니다.

wow[0][0]의 경우에는 *(*(wow + 0) + 0)이 되므로, &wow[0][0]의 타입은 pointer to int가 됩니다. 좌변과 우변의 데이터형이 일치하므로 당연히 문제가 발생하지 않습니다.

ps2의 질문에서는...
문자열 상수는 정적인 기억 수명을 갖는 전역 범위의 수정 불가능한 문자형 배열로 자동 생성됩니다. 문자열 상수를 생성하고 소멸하는 것은 전적으로 컴파일러가 처리하므로 아무런 문제 없이 사용할 수 없습니다.

댓글 달기

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