함수의 반환형이 int* 일 때, 주소말고 값을 반환해도 되는 까닭은 무엇인가요?

sungsoo1214의 이미지

C 공부를 하다가 의문점이 생겨서 글을 올립니다.

함수 선언을 int* add1(int a, int b); 과 같이 했습니다.

그리고 main()에서
(1) int sum1=add1(a,b);
(2) int* sum1=add1(a,b);
이렇게 했을 때

함수의 정의를
(1)
int* add1(int a, int b)
{
int tmp=a+b;
return tmp;
}
(2)
int* add1(int a, int b)
{
static int* tmp;
*tmp=a+b;
return &tmp;
}
2가지로 나눠서 해봤는데
둘다 값이 a+b 한 값으로 나왔습니다..
반환형이 포인터면 주소 값을 넘겨주고 그걸 포인터 변수가 받는게 맞는거 같은데,
(1) 처럼 그냥 값을 넘겨주고 값을 받아도 출력이 되는 까닭을 모르겠습니다.

warning: initialization makes integer from pointer without a cast [enabled by default]|
warning: return makes pointer from integer without a cast [enabled by default]|
이런 경고메세지가 뜨긴 했습니다.

제가 생각하기에.. 함수의 반환형이 int*면 return 값이 주소가 되야 하고 (1)같이 int형을 넘겨주면 에러가 나야 될꺼 같은데
값이 나오는게 이해가 되질 않습니다..

yukariko의 이미지

C에서는 형변환이 비교적 자유롭습니다.
다른 자료형을 리턴해주더라도 알아서 형변환 해줍니다.
물론 예외도 있습니다만..

주소라는것도 결국 저장되는 방식은 정수형이므로 연산 결과가 문제없이 나오게 됩니다.

shint의 이미지


int* add1(int a, int b)
{
	int tmp = a + b;
	printf(" tmp  %x\n", tmp);
	printf("&tmp  %x\n", &tmp);
	return (int*)tmp;
}
 
int* add2(int a, int b)
{
	static int* tmp;
	*(int*)(&tmp) = a + b;
	printf(" tmp  %x\n", tmp);
	printf("&tmp  %x\n", &tmp);
	return (int*)&tmp;
}
 
 
void main(void)
{
	printf("add1() %x  %d\n", add1(10, 20), add1(10, 20));
	printf("\n");
	printf("add2() %x  %d  %d\n", add2(10, 20), add2(10, 20), *add2(10, 20));
}
 
 tmp  1e
&tmp  33fd88
 tmp  1e
&tmp  33fd84
add1() 1e  30
 
 tmp  1e
&tmp  1f749c
 tmp  1e
&tmp  1f749c
 tmp  1e
&tmp  1f749c
add2() 1f749c  2061468  30
계속하려면 아무 키나 누르십시오 . . .

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

익명 사용자의 이미지

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