[완료][C] 타입이 다른 상수를 하나의 함수 인자로 받으려면??

yundorri의 이미지

안녕하세요,
하나의 함수로 서로다른 상수를 넘겨주고 출력을 하려 합니다.
좋은 방법이 없을지 고수님들의 의견 부탁드립니다.
가장 좋은 방법은 상수 자체를 넘기는 건데요, 예를들면,

    display( 365 );
    display( 'C' );
    display( 3.141592 );

제가 아직까지 실력이 안되서
아래는 제가 샘플로 작성중인 프로그램입니다.
이것도 정상적으로 동작하지는 않습니다.

void display( int type, void* constant )
{
    if( type == 1 ) printf( "const = %d\n", constant );
    else if( type == 2 ) printf( "const = %c\n", constant );
    else if( type == 3 ) printf( "const = %f\n", constant );
}
 
int main()
{
    int integer = 365;
    char character = 'C';
    double doubleval = 3.141592;
 
    display( 1, &integer );
    display( 2, &character );
    display( 3, &doubleval );
 
    return 1;
}

아래는 컴파일 결과입니다.

[yundorri@swdev main]$ g++ -Wall -o main main.cpp
main.cpp: In function 'void display(int, void*)':
main.cpp:56: warning: format '%d' expects type 'int', but argument 2 has type 'void*'
main.cpp:57: warning: format '%c' expects type 'int', but argument 2 has type 'void*'
main.cpp:58: warning: format '%f' expects type 'double', but argument 2 has type 'void*'
[yundorri@swdev main]$ ./main
const = -1075852468
const = K
const = -0.496786
[yundorri@swdev main]$ 

어떻게 해야 될까요. ㅠ.ㅠ
그리고 이런경우에 Default Parameter는 어떻게 지정할 수 있을까요?
예를들어

display( 3 );

이렇게 하면 default value로 0.0 이 출력되도록 하려면요???

klenui의 이미지

display 함수내의 constant앞에 별표를 붙여주면 되지 않을까요..?
요즘 공부하고 있는 boost::any가 저런 용도인것 같던데요..

yundorri의 이미지

저도 한 번 시도해 보았는데요,

[yundorri@swdev2 main]$ g++ -Wall -o main main.cpp
main.cpp: In function 'void display(int, void*)':
main.cpp:56: error: 'void*' is not a pointer-to-object type
main.cpp:57: error: 'void*' is not a pointer-to-object type
main.cpp:58: error: 'void*' is not a pointer-to-object type
[yundorri@swdev2 main]$                                    
vacancy의 이미지

#include <stdio.h>
 
void display( int type, void* constant )
{
    if( type == 1 ) printf( "const = %d\n", *(int *)constant );
    else if( type == 2 ) printf( "const = %c\n", *(char *)constant );
    else if( type == 3 ) printf( "const = %f\n", *(double *)constant );
}
 
int main()
{
    int integer = 365;
    char character = 'C';
    double doubleval = 3.141592;
 
    display( 1, &integer );
    display( 2, &character );
    display( 3, &doubleval );
 
    return 1;
}
yundorri의 이미지

감사합니다. 잘되네요. :->

하지만 변수가 아닌 상수를 바로 넣을 수는 없을까요?

    display( 1, 365 );
    display( 2, 'C' );
    display( 3, 3.141592 );

처럼 말입니다.
앞에 타입종류 식별을 위한 변수는 없을 수 없을것 같은데 맞나요???

vacancy의 이미지


http://wiki.kldp.org/wiki.php/CLanguageVariableArgumentsList

가변 인자를 사용하면 ( 사실 이런 용도는 아닙니다만 )
type을 늦게 결정할 수는 있습니다.
대신 prototype이 일정한 길이가 되지 않는다는 문제가 있군요.

일반적인 다른 방법이 있는지는 잘 모르겠네요.

yundorri의 이미지

말씀대로 해 봤는데 안되는 군요. 능력의 한계를 실감합니다. ㅠ.ㅠ
허나, 이 방법이 되었다 하더라도 문제나 한계는 존재합니다.
마지막에 '0'을 넣어줘야 된다는것과 상수값은 넘길 수 없다는 것, Default Parameter는
지정할 수 없는 것 말이죠.
원래 안되는건가요??

void display( int type, void* vars, ... )
{
    va_list argptr;
    int intval;
    char charval;
    double doubleval;
 
    va_start( argptr, vars );
    for( int i = 0; i < 2; i++ )
    {
        if( type == 1 ) { intval = (int) va_arg( argptr, int ); printf( "%d", intval ); }
        else if( type == 2 ) { charval   = (char) va_arg( argptr, int ); printf( "%c", charval ); }
        else if( type == 3 ) { doubleval = (double) va_arg( argptr, double ); printf( "%f", doubleval ); }
    }
    va_end( argptr );
    printf( "\n" );
}
 
int main()
{
    int intval = 365;
    char charval = 'C';
    double doubleval = 3.141592;
 
    display( 1, &intval, 0 );
    display( 2, &charval, 0 );
    display( 3, &doubleval, 0 );
 
    return 1;
}
whitelazy의 이미지

Quote:
말씀대로 해 봤는데 안되는 군요. 능력의 한계를 실감합니다. ㅠ.ㅠ
허나, 이 방법이 되었다 하더라도 문제나 한계는 존재합니다.
마지막에 '0'을 넣어줘야 된다는것과 상수값은 넘길 수 없다는 것, Default Parameter는
지정할 수 없는 것 말이죠.
원래 안되는건가요??

C에서는 Default Parameter는 아래에 설명하신분말대로 없습니다.
상수값을 넘길수 없는건.. void형으로 넘기는건데 C언어에서 parameter를 넘길때는 단순하게말하면
참조가아닌한 실제 값을 복사해서 넘겨줍니다 함수에서는 void형을 받아와야되는데 받아오려면 몇바이트를 복사해야되는거죠? ...
파라미터로 넘기기 전에 알고있는 자료형의 크기만큼 데이터를 복사해놓고 넘기면 끝이고
파라미터로 넘어오는건 이진수 덩어리일뿐이고 그 자료에 의미를 부여하는건 프로그래머 몫입니다... 몇바이트짜리 무슨데이터니까 몇바이트읽어라는거는요
void형이면 컴파일러는 나몰라라 상태일듯합니다만.....
답글쓰다보니 저도 잘 모르게되버렸는데 ㅎㅎ
void형은 몇바이트자료형일까요.. void *는 알듯한데요 void형자료에 값할당은 되나요? 대략 이런맥락일듯 싶습니다만
막 발로짜서 gcc로 void 타입 변수 선언하고 할당해보니까 안되는군요...
void.c: In function 'main':
void.c:5: error: variable or field 'voidtype' declared void

#include<stdio.h>
 
int main(void)
{
        void voidtype = 0x0000;
        return 0;
}

자료형 자체에 자료형 정보가 없는이상 프로그래머가 선언하는데로 자료형이 정의되고 형변환 하는데로 형변환 될뿐입니다
C언어에서 프로그래머가 직접 처리하거나 라이브러리라도 동원하지않는한 자료형정도는 알아서 처리해달라고하면 컴파일러가 탈납니다...

p.s. 배아파서 횡설수설좀 했습니다...; ㅎㅎ

kalstein의 이미지

template function을 이용하면 매우 괜찮네요.
뭐...사실 C++이면 template까지 갈것도 없고 함수오버로딩 기능만 이용해도 됩니다만;;;

그냥 C라면...글쎄요. 위에분 말씀대로 가변인자 사용말고는...특별히 없을것 같네요. ^^


------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/

익명 사용자의 이미지

C가 아니라 C++이로군요.

[yundorri@swdev main]$ g++ -Wall -o main main.cpp

Overload하세요.

void display(int x)
{
    printf("%d", x);
}
 
void display(char x)
{
    printf("%c", x);
}
 
void dispplay(double x)
{
    printf("%f", x);
}
 
    display( 365 );
    display( 'C' );
    display( 3.141592 );
semmal의 이미지

display(1,365);
display(2,'C');
display(3,3.141592);

display1(365);
display2('C');
display3(3.141592);

displayInt(365);
displayChar('C');
displayFloat(3.141592);

제가 보기에는 3가지 방법이 다 차이도 없고, 오히려 마지막 방법이 더 보기 좋지 않나요?

보통 C에서 type을 무시하고 함수를 정의할 때는 define문을 사용해서 매크로를 함수처럼 정의해서 사용합니다. 다만 이 경우는 printf를 쓰기 때문에 역시 알맞지 않습니다.

왜 꼭 display라는 함수만으로 해결하려고 하는지 이유를 안다면 조금 더 좋은 방법이 나오지 않을까 싶은데요.

------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

vacancy의 이미지

#include '<'stdio.h'>'
#include '<'stdarg.h'>'
 
void display(int type, ...) {
    va_list arg_ptr;
 
    va_start(arg_ptr, type);
    switch (type) {
        case 1: printf("%d\n", (int)va_arg(arg_ptr, int)); break;
        case 2: printf("%c\n", (char)va_arg(arg_ptr, int)); break;
        case 3: printf("%f\n", (double)va_arg(arg_ptr, double)); break;
        default: break;
    }
    va_end(arg_ptr);
}
 
int main(void) {
    int v_int = 365;
    char v_char = 'C';
    double v_double = 3.141592;
 
    display(1, v_int);
    display(2, v_char);
    display(3, v_double);
 
    return 0;
}
klyx의 이미지

정말 위에 익명분 말씀대로 g++로 컴파일 한다는건 C가 아니라 C++이니까 그냥 오버로딩하면 끝날텐데요-_-;

아니면 C++이니까, printf를 안쓰고, std::cout을 이용하는 템플릿함수를 만들면 오버로딩할 것도 없겠네요...

kslee80의 이미지

제목에 C 라고 적어놓으셨으니 g++ 컴파일러를 쓰고 있더라도 C 로 답변해 드려야 하는게 아닐까 싶네요.
(사실 C++ 이라면 몇몇 분이 말씀하셨듯이 overloading 으로 끝나는 문제죠)

그리고,
default argument 기능은 C 에 없습니다.

(비슷하게 한다면 두번째 아규먼트에 NULL 이 온다면 디폴트 값을 출력하는 식으로
작성하면 되겠지만, 이것을 원하시는건 아닐 것 같네요.)

yundorri의 이미지

글 올려놓고 좀있다가 갑자기 복통이 와서 병원신세 좀 지느라 답변이 늦었습니다.
많은 분들께서 답글 달아주셔서 정말 감사드립니다.

원래 제가 프로그래밍하고 있는 시스템에서 C++ 을 사용할 수 없게 되어있었습니다.

#ifdef __cplusplus
extern "C"
{
#endif
 
 . . . . . 
 중략
 
#ifdef __cplusplus
 }
#endif

이런식으로요... 그리고 Makefile내에서 -D__cplusplus 플래그가 있었죠.
그래서 default parameter를 사용할 수가 없었는데요,
저 라인을 없애기로 했습니다. @_@

너무 싱겁게 해결이 되어버렸지요~
그래도 많은 내용을 알게되어서 기쁩니다.

이렇게 근본적인 문제가 해결이 되니 자잘한 문제가 쉽사리 해결되는 경우가
자주 있는것 같습니다. 조금의 허탈을 동반하구요. ^^;

ps) 급성복통이 이렇게 괴로울줄 몰랐습니다. 다들 몸건강하십시요.

댓글 달기

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