[질문] C 구조체에서의 이상한 현상 ??

cjynim의 이미지

안녕하세요 C 언어를 공부하고 있는 학생입니다 ...

다름이 아니라 구조체에서 이상한 현상을 발견했는데요 왜 이러는지 이해가 가질 안습니다.

#include

struct P {
int a;
int b;
};
int main(void){
struct P s={1,2};
struct P k={3,4};

printf("%d %d %d %d\n", k, s, s, s); // 1
printf("%d\n", s); // 2
printf("%d\n", s); // 3
printf("%d\n", s); // 4

return 0;
}

위의 결과를 보면 우선, 2, 3, 4번은 s의 시작주소의 값이므로 1, 1, 1이렇게 출력 됩니다.

그럼 당연히 1번의 값은 k의 시작주소의 값인 3과 s의 시작 주소의 값이 1, 1, 1이 출력 되어야 할텐

데여 예상과 달리 3, 4, 1, 2라는 값이 찍혀서 나옵니다... 어째 이런 이상한 일이 일어나는거죠??

만약 1번의 코딩을 printf("%d %d %d %d\n", s, s, s, s); 이렇게 고치게 된다면 1, 2, 1, 2라는

값을 출력합니다... 디버그를 해서 각 구조체 변수의 값과 주소도 확인해 보았지만 전혀 변화가 없습니

다. 저의 얄팍한 지식으로는 도저히 이 현상을 이해할 수 없습니다.. 고수님들 도와주세여 ~

poibe의 이미지

printf("%p \n",s);로 해보심..

Fly to the SKY~~~~~~

"According to your faith, be it unto you!!"

cjynim의 이미지

위의 경우 일반 변수로 &s를 해야만 주소가 나옵니다 ~!! 포인터변수였다면 위 분 말씀이 맞지만여

구조체 변수도 일반 변수와 다를것 없이 위 처럼 사용하면 처음 요소의 값을 출력하게 되어 있거든요...

Darkcircle의 이미지

printf("%d %d %d %d\n", s, s, s, s);
가 아니라

printf("%p %p %p %p %p %p\n", &s, &s, &s, &s, &s, &s);

....
결과가 어떨지 궁금하군요...

================================================
니네 군대에서 멀쩡한 몸으로 18시간 자봤어? ㅋㅋㅋ

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

cjynim의 이미지

냉무 ~

cjynim의 이미지

보통 앞의 자료형이 있는것은 메모리 할당과 데이터의 표현 범위를 알려주잖아여 ...

그러니까 예를 들어 int 형이면 4byte(보통 32비트 컴퓨터에서..)공간을 할당하고 자신의 변수

시작주소에서부터 int형이니까 4byte를 표현해 주잖아여 ... 그런데 struct P일 경우 시스템에서

요구하는 표현범위가 아니므로 값이 이상하게 나오는거 아닌가요 ??

익명사용자의 이미지

%d가 구조체 출력하라고 있는 지시자인가요?
일부러 고의적으로 틀린 코드를 적어놓고
잘못된 결과가 왜 나오는지 묻는 그 심보가 궁금합니다.
이런 쓸데없는 걸 이해하면 뭔가 대단한 걸 배운 것 같은 느낌이 듭니까?

컴파일러는 바보같은 프로그래머의 잘못된 코드가
어떠한 결과를 불러오는지에 대해서는
절대로 보장해주지 않습니다.

익명사용자의 이미지

저런 결과가 나오면 안되는 걸로 알고 있는 지식에 반하는 결과물로 인한
궁금함을 비아냥 거리는 건 아니라고 봅니다.
언어 공부하면서 궁금한거나 어라? 하는것을 알아보는 것을 매도 하는건
별로 좋은책 많으니 거기서 시키는 대로만 생각하고 행동해라
이정도 수준에 빠져 있을수 밖에 없습니다.

그냥 printf("%d",s)를 %d구지 값을 보시고 싶다면 구조체 역시 주소가 있으니 주소값을보면
변화는 없이 값이 나올텐데 이미 할당? %d만을 여러개 늘려서 해보면 s라는 것이 메모리를 %d개수만큼
읽어 들이는 것을 볼수 있을텐데요. 그래서 k의 메모리 주소부분까지 읽어 들임니다. 저역시 확실한 이윤
별로 관심을 안두었던 부분이라...

처음 공부하시는 학생이라면? 여러가지 해보는것도 좋다고 봅니다. 꼭 이렇게만 해라식보다는 좀 쓸데없는
것이라고 치부되더라도 그냥 이건 이거야... 보단 이건 이렇게 되서 이거야... 가 공부하시는 분 입장에선
더 좋지 않을까요?

마지막으로 QnA인것을 명심하시고 비아냥은 삼가하는게 좋을꺼 같습니다.

bootmeta의 이미지

고의적으로 틀리게 작성하려고 한 것은 아닌 듯 합니다.

만약 고의적으로 틀렸다 하더라도 틀린 코드의 출력에 대해 나름대로 고민해보는 것도 나름대로의 공부하는 방법일 수도 있습니다.
개인의 입장에서는 대단한 것을 배웠다고 생각될 수도 있고, 도움이 되었을 수도 있습니다.

espereto의 이미지

struct P s={1,2};
struct P k={3,4};

printf("%d %d %d %d\n", k, s, s, s); // 1

printf의 구현에 따라, 플랫폼에 따라 다를 순 있겠지만 위의 경우는 아래처럼 설명이 가능할 것 같습니다.

int를 4바이트로 가정하고,
s 는 총 8바이트의 데이터입니다.
k 역시 촐 8바이트입니다.

printf("...", k, s, s, s); 를 실행하기위해,
format string의 pointer, k, s, s, s가 스택으로 들어갑니다.
stack (ptr, k.a, k.b, s.a, s.b, s.a, s.b, s.a, s.b, s.a, s.b)

printf는 format string의 pointer에 접근해서 분석을 하고,
stack (k.a, k.b, s.a, s.b, s.a, s.b, s.a, s.b, s.a, s.b)

분석된대로 스택에서,
%d에 맞게 int형으로 4바이트씩 꺼내서 출력합니다.
즉, k.a, k.b, s.a, s.b 순서로 3, 4, 1, 2가 나옵니다.

전 요즘은 주로 ARM 위에서 많이 작업하는데, 구조체 변수 자체를 파라미터로 넘기는 경우, 구조체의 변수의 데이터 전체가 스택으로 넘어가더군요.

shivan의 이미지

음...

이런 구조군요^^...

cjynim의 이미지

이제야 궁금증이 해결 되었습니다...

저는 printf가 저런 과정을 거쳐서 작동 되는줄은 정말 생각하지 못했었습니다 ...

많은 공부가 되었습니다 ...

그럼 좋은 하루 되세여 ~!!

poibe의 이미지

..^^

Fly to the SKY~~~~~~

"According to your faith, be it unto you!!"

댓글 달기

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