기초질문입니다만, char a[1] 과 char a

익명 사용자의 이미지

char a[1];
char b;

똑같이 기억장소1바이트를 차지하는 두개의 차이는 뭔가요?
배열과 non-배열의 차인가요?

익명 사용자의 이미지

char a[1];
char b;

에서 a는 포인터이므로 4바이트를 차지할 터이고
a[1] 는 1바이트를 가지고 있을겁니다.
그리고 b는 1바이트만 차지할겁니다.
익명 사용자의 이미지

a의 타입은 '배열'입니다. 포인터가 아닙니다.

C/C++에서 '배열'이나 '함수' 등의 타입은 non-scalar 타입으로,
scalar로써 식 내에 쓰일 경우 scalar 값인 '배열 포인터', '함수 포인터' 등으로 각각 변환되어 처리될 뿐이지,
그 자체가 포인터는 아닙니다.

다시 말해,

char array[200];

에서 sizeof array 는 200이지, sizeof (char *) 와 같은 값이 아니라는 것입니다.

===

http://cafe.daum.net/codeinside

익명 사용자의 이미지

a[1]
에서 a는 포인터상수로 알고있습니다.
처음부터 할당된 값의 상수도 아니구요.
그런데 4바이트를 차지(?)하나요?
궁금하네요. 초보라서 ^^

익명 사용자의 이미지

a는 어드레스를 의미하며, 32 bit 기계에서 4byte 입니다.

fprintf(stderr, "sizeof(&a) -> %d", sizeof(&a));

와 같이 주소의 크기를 찍어보세요.

손님 wrote:
a[1]
에서 a는 포인터상수로 알고있습니다.
처음부터 할당된 값의 상수도 아니구요.
그런데 4바이트를 차지(?)하나요?
궁금하네요. 초보라서 ^^
체스맨의 이미지

논리적인 크기는 4바이트가 맞습니다만,
포인터 상수는 메모리 공간을 차지하지는 않습니다.

Orion Project : http://orionids.org

박계현의 이미지

char a[1];
char a;

"char a[1];"이건 1개의 char형 값을 가진 배열을 생성한것입니다.
또한 이 배열의 첫번째 원소인 a[0]은 "char a;"라고 선언한 변수
와 동일합니다.

또한 배열 a의 주소를 알고자 할때는 본 자신의 배열이름이름이며,
하지만 "char a;"의 주소를 알고자 할때는 & 연산자를 앞에 붙여야만
합니다.

sizeof a // 변수 a일때 sizeof (char) 반환
sizeof a // 배열 a일때 sizeof (char) x 배열첨자길이 반환

sizeof 연산자를 이용해 데이터 객체의 크기를 리턴을 해보면
"char a;"의 sizeof a는 1byte를 반환하지만,
"char a[1];"의 sizeof a또한 1byte를 반환합니다.

char a[4];
sizeof a; // sizeof(char) x 4 = 4byte 반환

여기서 중요한 것은,
배열의 sizeof는 배열 첨자의 개수 x sizeof(데이타형) 라는 것입니다.
"char a[4];"의 sizeof a는 4byte를 반환하겠죠?

char a[4];
sizeof &a[1]; // a[1]을 가리키고 있는 포인터의 크기 4byte 반환

하지만, "char a[4];"의 sizeof &a[1]은 1byte일까요? 아닙니다.
a[1]이란 1byte의 데이타를 가르키고 있는 포인터의 크기이므로
4byte가 정답입니다. 이상입니다 ^^
운형의 이미지

일반적으로 상수를 사용하면 그 상수는 힙에 저장됩니다.

int a[1];
은 정수형 데이터 하나를 저장하는 공간을 스택에 만듭니다. 이건
int b;에서도 마찬가지 입니다.

그런데 문제는 a라는 포인터상수 입니다.
이녀석은 분명 4바이트(운영체제에 따라 2바이트)의 공간을 차지하는
상수 입니다. 이 상수는 어디에 만들어질까요.
char *ptr = "abcde";라고 선언했을 경우 ptr은 스택에 4바이트를 차지하는
변수로 만들어지고 "abcde"는 힙영영에 6바이트로 만들어지죠.

이것과 같다고 봅니다. a[1]에서의 a는 힙영역에 생성이 될겁니다. :idea:

Do you think that's the air you are breathing now?

twinwings의 이미지

"abcde" 는 상수라서 스택에 생성될텐데요?

최종호의 이미지

상수는 heap에 만들어지지 않습니다.
굳이 따지자면 상수는 코드 (세그먼트) 에 *박혀* 있습니다.

예로 드신
char *ptr = "abcde";
에서 "abcde" 는 데이터 영역에 생성되며,
ptr은 함수 안이라면 말씀하신대로 스택에 생성됩니다.

함수 내에서 정의된
char arr[6] = "abcde";
의 경우, "abcde"는 데이터영역에 생성되며,
함수호출시 스택의 해당 공간으로 복사됩니다.

이 경우 arr 이 문제일텐데,
printf("%s\n", arr);
이라는 문장을 수행하려면 arr 값을 넘겨야 할텐데,
이 값은 스택이나 데이터영역에 있지 않고,
힙에는 더더욱이나 저장되어 있지 않습니다.
이 값은 코드에 존재합니다.
컴파일시에 C는, arr로 대표되는 char 6 바이트가 스택내의 어느 위치에
저장될지를 알 수가 있습니다. (사실은 컴파일러가 그 위치를 지정해 주어야 겠지요.) 따라서 컴파일러는 arr의 값을 다른 곳에 저장하는 것이 아니라
그 값을 코드에 직접 포함하고 있는 것입니다.

다음은 C 코드와 이에 대응되서 생성된 어셈블리코드입니다.

        char    arr[10] = "123456789";
        .
        .
        .
        printf("%s\n", arr);

.LLC2:
        .asciz  "%s\n"
.
.
.
        sethi   %hi(.LLC2), %o0
        or      %o0, %lo(.LLC2), %o0
        add     %fp, -40, %o1
        call    printf, 0

(SunOS host 5.7 Generic_106541-23 sun4u sparc SUNW,Ultra-80,
gcc 3.0.3)

이 중 arr의 값이 전달되는 부분은 call printf, 0
바로 앞 부분에 있는 add %fp, -40, %o1 입니다.

즉, -40이 fp (frame pointer. 해당 함수호출의 스택 프레임) 와 합해져서 값을 곧바로 만들어 낸 것입니다. 즉, arr의 값은 일반적인 변수들과는 달리 데이터나 스택 영역에 저장되지 않지만 굳이 말하자면 코드에 박혀있다고 말할 수 있습니다.

.LC2:
        .string "%s\n"
        .
        .
        .
        leal    -40(%ebp), %eax
        pushl   %eax
        pushl   $.LC2
        call    printf

위 어셈블리코드는
Linux host 2.4.2-2wl #1 금 6월 8 05:21:58 KST 2001 i686 unknown,
gcc 2.96
에서 생성된 것입니다. 어셈블리 문법은 조금 틀리지만 역시나 arr의 값이 코드에 직접 들어있는 것을 확인하실 수 있습니다.

조금 다르면서도 비슷한 얘기로,

func()
{
    int    a;
    int    b;

    b = a + 5;
}

인 경우 상수값 5도 코드에 직접 들어가 있습니다.

        ld      [%fp-20], %i0
        add     %i0, 5, %i0
                         ===
        st      %i0, [%fp-24]

어셈블리의 어드레싱 모드 중 immediate 모드가 여기에 해당되겠습니다.

운형의 이미지

제가 부정확하게 알고있는 것 정정해주셔서 감사요.. (_ _)

Do you think that's the air you are breathing now?

댓글 달기

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