C 포인터 연산 질문입니다.

cococo의 이미지

포인터 연산 관련 질문입니다.
지금까지 문제없이 쓰고 있었다는 게 더 신기합니다만...부끄러운 이야기입니다.

어쨌던, 이전에 전혀 의심하지 않고 쓰던게 문법에 걸려서 질문드려 봅니다.

코드는 아래와 같습니다.

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

char (*list1)[4];
char *(list2[4]);
char str1[] = "aaa";
char str2[] = "bbb";
char str3[] = "ccc";

list1[0] = str1; // 문법오류
list2[4] = str1; // 컴파일성공. 실행성공.

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

보시면 아시겠지만, 각 문자열( str1 ~ str 3 )을 관리하는 별도의 포인터를 사용하려는 겁니다.
그런데, 문자열의 포인터 할당이

list1 변수 형식은 안되고
list2 변수 형식은 되는군요.

list2 는 이해가 갑니다.
list2[4] 에서 이미 list2 는 1차원 포인터 ( *list2 ) 니까.
그걸 * 로 다시 감싼다면 ( = *(list2[4]) )
list2 는 더블 포인터고, 고로 list2[0] 은 1차원 포인터니까 할당에 상관없겠죠.

근데, list1 은 왜 안 되는 걸까요?
list1 도 *list1 으로 선언했으니 이미 1차원 포인터고,
그걸 4개 선언했으니 ( = (*list1)[4] )
당연히 list1 도 2차원 포인터가 되어서,
list1[0] 은 당연히 1차원 포인터가 되는거 아닌가요?
오히려 이쪽이 더 안정적이어야 할 것 같은데 막상 해보면

list1[0] = str1;

은 에러가 납니다.

혹시 아시는 분, 조언 부탁드립니다.

이상입니다. 좋은 하루 되시기 바랍니다.

라스코니의 이미지

1) char (*list1)[4];
는 char *ptr 의 4개 배열을 선언하는 것입니다.
중요한 것은 char *ptr 이라는 것은 한 문자를 가르킬 수 있는 포인터입니다. 따라서

list1[0] = str1; // 문법오류
는 안되지만
list1[0] = &str1[0]; 는 오류가 안날것 같은 생각이 드네요.

2) char *(list2[4]);
는 char str[4]의 포인터형입니다. 즉 이 형은 4개 문자를 가르킬 수 있는 일종의 스트링 포인터입니다.
그래서
list2[4] = str1; // 컴파일성공. 실행성공
과 같이 가능한 것입니다.

그리고 list2[4]가 아니라 list[3] 가 되어야 하겠죠

Prentice의 이미지

http://cdecl.org/

  • declare list1 as pointer to array 4 of char
  • declare list2 as array 4 of pointer to char

cdecl 받아서 설치하시면, 영어로 치면 코드로 변환해 주고, explain char (*list1)[4]; 치면 영어로 변환해 줍니다.

HDNua의 이미지

The C Programming Language의 코드가 떠오릅니다.

저는 이렇게 생각했습니다.

cococo의 이미지

라스코니 님, 프랜티스(?) 님, 고해상도Nua 님. 답글감사합니다.

이전 코드를 보니까, 아무 생각없이( = 이전에 쓰던대로 )

char *list[4];

이렇게 썼었군요.

말씀해주신 사이트에서 영어로 해석을 보니 뭐가 문제인지 알겠네요.

char *list1[4]; // declare list1 as array 4 of pointer to char -> 원하던거 = 포인터 4개.
char (*list1)[4]; // declare list1 as pointer to array 4 of char -> 소괄호가 대괄호랑 따로따로 있는데도 이렇게 되는게 의외 (= 문자열 4칸짜리 포인터 1개 )
char *(list1[4]); // declare list1 as array 4 of pointer to char -> *list1[4] 와 동일.

char *list1[4] 를 명시적으로 쓰려고 char (*list1)[4] 로 한 건데 , *list1[4] 가 *(list1[4]) 와 같다는게 의외군요. 이해가 안 되는 건 아니지만( 연산은 오른쪽 먼저이니까 ),
납득하기는 힘들군요.( 포인터 4개 선언이니까 (*c) x [4] 이어야 하는거 아니었나? )

이상입니다. 좋은 하루 되시기 바랍니다.

익명 사용자의 이미지

1.(char *) 자료형
2.char 자료형
3.(char *) 자료형

2번 자료형은 정확하게 어떻게 되나요?

cococo의 이미지

죄송합니다. 질문을 이해하지 못하여 답변이 어렵네요.

의도는

"문자열을 관리하는 리스트" 입니다.

그러므로

(char *) x N개 포인터

정도 됩니다.

HDNua의 이미지

1. 가장 간단하게는, 이렇게 생각하는 것이 편하겠습니다.

char (*var)[4];

괄호를 가장 먼저 해석하므로, var는 포인터입니다. 그러면 남는 부분은 char [4] 배열이므로, var는 배열에 대한 포인터가 됩니다.

2. The C Programming Language에는 C에서 선언이 어떤 형태를 띠고 있는지를 설명하는 부분이 있습니다.
원래는 더 자세히 설명하고 싶었지만, 그러면 너무 글이 길어져서 이해할 수 있는 정도로만 설명했습니다.
혹 더 자세한 설명을 원하시면 답글 달아주세요. (글이 꽤 깁니다)

저는 이렇게 생각했습니다.

댓글 달기

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