기초적인 c문제...
글쓴이: cjy1126 / 작성시간: 금, 2003/04/11 - 12:09오후
#include <stdio.h> int fn(char []); int main() { char str[] = "345"; printf("main = %d\n", sizeof(str)); fn(str); return 0; } int fn(char str[]) { printf("%s\n", str); printf("fn = %d\n", sizeof(str)); return 0; }
결과값입니다.
main = 4 345 fn = 2
이렇게 되는 이유가 char str[]이 넘어올때 포인터로 넘어와서 인가요?
2군데서 &str로 주소를 찍으니까 main은 65520, fn은 65518이 나오네요.
그럼 원래값이랑 넘겨진값이 다른것 같은데...
함수의 인자가 넘어가면서 char는 int로 바뀌는거랑 관련이 있는건가요?
아니면, str[]를 배열 전체가 아닌 첫주소만 넘겨서인가요?(저는 이것같은데... 메모리가 어떤식으로 되는지 모르겠네요. stack이라서 나중에 생긴 배열을 가르키는 포인터의 값이 더 작은건가요?)
이것 저것 너무 어설프게 알아서 힘드네요.
함수의 인자가 char에서 int로 바뀐다는거랑 제 코딩의 str이 어떤식으로 변한건지 답변 부탁드립니다 :oops:
Forums:
main에선 array이고, 서브함수에서는 pointer입니다.
메인에선 당연히 해당 array의 크기인 4가 잡힙니다.(맨끝 널종료 포함)
그리고 함수로 넘겨줄때는 array의 시작주소가 넘어가니까 2가 맞습니다.(그런데 도스에서 프로그래밍 하시나 봅니다. 16bit 주소체계인것을 보니...)
근데 함수 인자가 char -> int로 바뀐다는게 무슨 말씀이신지?
서브함수는 원래 포인터를 받는 것으로 선언된것 맞습니다.
========================================
* The truth will set you free.
처음에 dos에서 c를 배워서 tc가 너무 편해서요.vi를 잘못쓰
처음에 dos에서 c를 배워서 tc가 너무 편해서요.
vi를 잘못쓰는 이유도 있지만요 ^^;
형변환이 된다는 말이 2군데서 나오는데, 같은 의미인지는 모르겠습니다.
the c programming language 2nd 42쪽에 나오는 말인데요.
함수호출에 의해 매개변수가 함수로 전달될 때에도 형변환이 일어난다. 함수선언부분(function prototype)이 없으면 char, short, int, float는 duoble로 된다. 이것이 바로 함수가 char이나 float로 호출될 때에도 함수 매개변수들을 int와 double로 지금까지 선언해온 이유이다. (앞 예제 다 뒤져도 이런 예제가 없네요 -_-);
그리고 전에 이곳하고 백두대간 c에서 봤을때 char 인자가 넘어갈떄 int로 변환되서 넘어가서 다시 char이 된다는식으로 들었거든요. 아닌가요? :oops:
main()에선 변수 str이 배열로 선언되어 있으므로 sizeof()
main()에선 변수 str이 배열로 선언되어 있으므로 sizeof() 연산의 결과 4가 나옵니다.("345\0")
fn()에선 str이 포인터로 선언되어 있으므로(함수 인자 선언시 배열형태로 선언하더라도 포인터형으로 간주) sizeof() 연산의 결과는 해당 시스템의 포인터 크기에 의해 결정됩니다. cjy1126님의 경우 2가 나온걸 보면 도스환경인 것 같네요.(near pointer)
형변환은 main() 함수에서 fn(str)을 호출할 때 발생되는군요.
(char *)str -> (int)str
도스환경에선 int나 pointer나 둘 다 2byte이고 정수값이므로 에러 없이 컴파일은 되겠지만 가능하면 명시적으로 형변환을 해주시거나 main() 시작 전에 fn() 함수의 proto type을 선언해 주시는 것이 좋습니다. 그렇지 않으면 컴파일러는 선언되지 않은 함수의 모든 인자가 int형이라고 간주하고 형변환을 하게 되거든요.
fn() 함수의 관점에서 보자면 호출되는 시점에서 넘어오는 값은 int형으로 넘어오겠지만 이 역시 int -> pointer로의 형변환이 같은 2byte에 정수값이므로 에러 없이 컴파일 됩니다. 그리고 원래의 데이터값이 char *(pointer)가 맞으므로 수행결과도 정상적으로 나타나구요.
s(˘∼˘*)z,·´″"`°³о$ √(´∀`√)... (˘ヘ˘ㆀ)a
윗분이 말씀을 잘해주셨네요.
그래서 항상 함수의 원형을 선언해주는 것이 좋다고 하는 이유가 있는 것입니다.
gcc에선 원형없이 컴파일하면 implicit declaration of function 이라고 워닝을 쭉쭉 뱉어내죠... 항상 원형을 써주는 버릇을 들이는게 좋습니다.
========================================
* The truth will set you free.
sizeof 는 컴파일 타임에 결정되는 연산자입니다.메인경우 4바
sizeof 는 컴파일 타임에 결정되는 연산자입니다.
메인경우 4바이브 배열이라 4.
fn 경우엔 포인터라 2.
screen + vim + ctags 좋아요~
잘 이해가 안됩니다.
이해가 안되는 부분들...
1. 원형을 선언하라고 하시는게 int change(char str[3]);
이렇게 선언하라는건가요?
이렇게 선언해도 결과는 같게 나오거든요.
지금 제가 넘긴게 str[] 니까 포인터를 넘긴거라고 써주셨는데...
함수 인자 선언시 배열형태로 선언하더라도 포인터형으로 간주
2. 포인터라고 명시했는데, int로 넘어오나요?
fn() 함수의 관점에서 보자면 호출되는 시점에서 넘어오는 값은 int형으로 넘어오겠지만
3. 주소로 안받고 main()에서와 같은 배열 자체로 받는 방법은 없나요?
array의 이름, 함수 인자
안녕하세요, 검은해라고 합니다.
질문자님께서 모르고 계신 것처럼 보여서 글을 씁니다. 이미 알고 계시다면 죄송합니다.
char foo[]; 처럼 배열을 선언하셨을때 foo는 foo[0]의 주소를 말합니다. 즉 foo는 foo[] 배열의 첫 요소를 가리키는 포인터가 됩니다. 보통 포인터와 다른 점이 있다면 포인터 변수가 아니라 정말 순수한 주소값으로서의 포인터라는 점입니다.
올려주신 소스는 아래와 같이 수정해도 동일한 소스일 것입니다. str과 input의 차이에 대해 생각해보세요.
첨부...
1. int change(char str[3]) 해도 결과는 동일...
-> char str[] 와 char str[3] 는 C 에서는 동일한 것임.
2. 포인터라고 명시했는데, int로 넘어오나요?
-> 포인터가 인티저의 메모리 크기를 갖는다는 말이겠죠..
3. 주소로 안받고 main()에서와 같은 배열 자체로 받는 방법은 없나요?
-> 주로로 받는게 가장 좋은 방법이죠,,
그게 싫다면, 구조체를 사용하세요..
그런데 별로 권장하고 싶지 않네요..
댓글 달기