[완료] 다시 질문드립니다...맨 밑에...C공부하다 궁금해서 여쩌봅니다. #define과 typedef

taehun의 이미지

C공부하다 궁금해서 여쩌봅니다. #define을 써서 typedef를
구현해도 되나요?

예를들어 #define int_aa int

typedef int int_aa

같은 건가요?

초보 질문드립니다.

익명 사용자의 이미지

전혀 다릅니다.

#define은 그냥 단순 치환입니다.

이걸로 typedef를 대체하면 에러메시지도 프로그래머가 이해하기 힘들게 뜨고,
또한 포인터나 배열, 함수 등이 결합된 복잡한 타입에 대해선 형 정의가 어렵습니다.

무엇보다 #define을 쓴다 해서 생기는 이점이 전혀 없습니다.

taehun의 이미지

#define int_aa int

위와같이 해놓으면

프로그램에서
int_aa abc = 10

이렇게 코딩하면 전처리기가 int_aa 를 int로 바꿔주고
컴파일 되는것이 아닌가요?

익명 사용자의 이미지

컴파일이 안된다는 얘기가 아니라...

#define은 단지 소스를 기계적으로 치환하기 때문에
컴파일러는 int_aa라는 타입이 있는지 없는지조차 알 수가 없으며,
그냥 이걸 모두 int로 해석합니다.
이게 문제가 되는 부분이 대표적으로 에러/경고 메시지 입니다.

#include <stdio.h>

#define typeA int
typedef int typeB;

int main(void)
{
float f;
typeA *pa = f;
typeB *pb = f;
return 0;
}

포인터형에 float형을 대입하므로 컴파일시 에러가 발생해야 하는 코드인데... gcc로 컴파일을 해보면

1.c: In function 'main':
1.c:9:14: error: incompatible types when initializing type 'int *' using type 'float'
1.c:10:14: error: incompatible types when initializing type 'typeB *' using type 'float'

윗줄은 int *형이라고 메시지가 뜨는데 아랫줄은 typeB라고 메시지가 뜨지요?

매우 길고 복잡한 소스 내에서 타입과 관련한 에러메시지가 발생했을때...
우리가 알고 있는 이름이 안뜨고 엉뚱한 타입 이름이 뜬다면
프로그래머가 대처하기가 상당히 난감하겠죠.

hwatk의 이미지

define은 pre-processor가 치환하는데 반해, typedef는 "마치 새로운 type처럼" compiler가 인식할 수 있기에,
define으로 극복하지 못하는 경우를 처리할 수가 있습니다.

Example 1.

typedef char *String_t;
#define String_d char *
String_t s1, s2; // s1, s2모두 char* 형으로 선언.
String_d s3, s4; // s3은 char*, s4는 char.

Example 2.

typedef char char_arr[];
char_arr my_arr = "Hello World!\n";

(http://wiki.answers.com/Q/What_is_difference_between_define_and_typedef_in_c)

taehun의 이미지

String_d s3, s4; // s3은 char*, s4는 char.

에서 왜 s4가 char형으로 되나요?
char* s3, s4 이면 s3,s4 둘다 char* 이지 않나요?

example2에서

typedef 기존의 데이터형 새로운 데이터형 이름
이라고 알고 있는데

typedef char char_arr[]; //즉 char = char_arr[]

얼핏보기에
char_arr my_arr = "Hello World!\n";
는 char_arr[] my_arr = "Hello World!\n"; => char my_arr = "Hello World!\n" 으로 변할거 같은데

어떻게 char_arr my_arr 이 char my_arr[]이 되나요?

익명 사용자의 이미지

얼핏보지 말고 자세히 보시길 바라구요...
C언어의 타입에 대한 깊은 고찰이 필요하실듯 합니다.
아울러 물음에 대한 대답은 이미 링크된 사이트에 다 있네요.

익명 사용자의 이미지

char * s3, s4;

이건

char * s3;
char * s4;

가 아니라

char * s3;
char s4;

와 같습니다.

char a3[3], a4;

이 코드에서 a3은 배열이지만 a4는 char형인 것과 동일한 이치입니다.

혹은 이렇게 생각을 해보세요.

char * s3, s4;
char s4, * s3;

위 두줄은 같은 의미를 가진 코드입니다.
위의 두줄이 서로 다른 의미를 가진 코드라면 좀 이상하겠죠?

example2에서

char = char_arr[]이 아니고
char_arr라는 타입이 char형 배열과 같은 데이터형일 뿐입니다.

typedef는 변수 선언과 똑같은 문법을 사용합니다.

char char_arr[];

이런 코드가 있다면 변수 char_arr은 char형 배열이 되겠죠?

이제 typedef를 붙여봅시다.

typedef char char_arr[];

데이터형 char_arr은 char형 배열과 같은 데이터형이 됩니다.

taehun의 이미지

친절한 답변 감사드립니다.
이제 이해가 가네요 ^^

익명 사용자의 이미지

char* s3, s4;일때 s4도 char *형이 아니냐고 오해하는 경우를 종종 보는데...
[]과 같이 생각하면 좋을듯 합니다.

char s3[2], s4;를 두고 s4도 배열이지 않냐고 오해하는 경우는 잘 보지 못했습니다. ㅎㅎ
*도 []처럼 이름 뒤에 쓰게 만들었으면
*를 char* s3라고 쓸지 char *s3라고 쓸지 같은 식상한 논쟁도 안생겼을텐데 싶은 ㅋ

물론 어디까지나 C/C++ 이야기입니다.
다른 언어는 그 언어가 어떻게 정했냐 나름 ...

taehun의 이미지

친절한 답변 감사드립니다.
이제 이해가 가네요 ^^

taehun의 이미지

typedef는 변수 선언과 똑같은 문법을 사용합니다.

char char_arr[];

이런 코드가 있다면 변수 char_arr은 char형 배열이 되겠죠?

이제 typedef를 붙여봅시다.

typedef char char_arr[];

데이터형 char_arr은 char형 배열과 같은 데이터형이 됩니다.

--------------------------------------------
질문)

typedef char [] apple; 이 아니라, typedef char apple[]; 을 쓰는게 이해가 어려웠습니다.

typedef char char_arr[]; 이 char_arr 이 char 형 배열이 된다면

char_arr banana 로 써야하는지,
char_arr banana[] 로 써야하는지 궁금합니다.
char_arr이 이미 int [] 을 의미한다면 char_arr 그 자체가 이미 []을 포함하고 있다고 봐도 되는건가요?

taehun의 이미지

만약 char_arr banana[] 가 맞다면

typedef int banana

typedef int banana[]

가 똑같은게 되나요?

typedef int banana
banana apple[];=> int apple[];
이것과

typedef int banana[]
banana apple[] => int apple[];

둘이 똑같게 생각되는데...

taehun의 이미지

만약 char_arr banana[] 가 맞다면

typedef int banana

typedef int banana[]

가 똑같은게 되나요?

typedef int banana
banana apple[];=> int apple[];
이것과

typedef int banana[]
banana apple[] => int apple[];

둘이 똑같게 생각되는데...

익명 사용자의 이미지

우선 제가 좀 틀렸네요.

char char_arr[];

요렇게 선언하면 당연히 에러가 날 겁니다. 크기 지정을 안했으니까요.

char char_arr[3]; 이게 맞고
typedef char char_arr[3]; 요게 맞습니다.

그러면 char_arr banana; 라고 써도 되느냐? 됩니다.
이때 banana는 크기 3인 char형 배열이 되는거죠.

char_arr banana[4]; 으로 쓰면? banana는 char형 이차원 배열이 됩니다.
banana는 char banana[3][4]; 와 같은 배열이 됩니다.

댓글 달기

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