char * 과 char ** 의 수정

alwaysN00b의 이미지

제목이 좀 이상한데...

그동안 '잘' 이해했다고 믿은 포인터가 궁금증을 낳게 하는군요..

int foo1(char *a){
    a = malloc("foo1");
    if(a != NULL) return 0;
    else return -1;
}

int foo2(char **a){
    *a = malloc("foo2");
    if( *a != NULL ) return 0;
    else return -1;
}

위 두 함수는 서로 다른 것인가요?
정태영의 이미지

alwaysN00b wrote:
제목이 좀 이상한데...

그동안 '잘' 이해했다고 믿은 포인터가 궁금증을 낳게 하는군요..

int foo1(char *a){
    a = malloc("foo1");
    if(a != NULL) return 0;
    else return -1;
}

int foo2(char **a){
    *a = malloc("foo2");
    if( *a != NULL ) return 0;
    else return -1;
}

위 두 함수는 서로 다른 것인가요?

예 다른겁니다... char* a 라고 하면 a에는 a가 가리키는 메모리 주소만이 복사가 됩니다. a가 가리키는 메모리주소값 자체를 고치고 싶다면 char** a가되어야 하거든요

c에서는 정확하게 call by reference 가 없습니다... call by value 를 통해 call by ref 를 흉내낼 뿐이죠

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

alwaysN00b의 이미지

정태영 wrote:
alwaysN00b wrote:
제목이 좀 이상한데...

그동안 '잘' 이해했다고 믿은 포인터가 궁금증을 낳게 하는군요..

int foo1(char *a){
    a = malloc("foo1");
    if(a != NULL) return 0;
    else return -1;
}

int foo2(char **a){
    *a = malloc("foo2");
    if( *a != NULL ) return 0;
    else return -1;
}

위 두 함수는 서로 다른 것인가요?

예 다른겁니다... char* a 라고 하면 a에는 a가 가리키는 메모리 주소만이 복사가 됩니다. a가 가리키는 메모리주소값 자체를 고치고 싶다면 char** a가되어야 하거든요

c에서는 정확하게 call by reference 가 없습니다... call by value 를 통해 call by ref 를 흉내낼 뿐이죠

아, 정말 시원한 답변 감사드립니다. :D

Quote:
c에서는 정확하게 call by reference 가 없습니다... call by value 를 통해 call by ref 를 흉내낼 뿐이죠

언제나 시작

ㅡ,.ㅡ;;의 이미지

c에서 call by reference 가 되죠...

Passing by Reference 가 안되죠..


----------------------------------------------------------------------------

alwaysN00b의 이미지

passing by reference 와 call by reference 의 차이점이 무었인가요?

확실히 몰라 답변 부탁드립니다.

ps. passing by value 와 call by value 의 차이점은 무엇인지요?

언제나 시작

ㅡ,.ㅡ;;의 이미지

아래 잘설명된거같네요..

Quote:
이 강좌의 대상은 C의 초보를 위해서 재미있을만한 얘기를 중심으로
한 강좌입니다. 많은 성원 바라며...
참고로 참고 문헌은

C & C++ Efficiency 라는 책입니다.
..........................

2. 웃기는 & Passing-by-reference (C++) '98/03/14
'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'`'
......................................

#include

struct int_vac{
int data[100];
};

// Call by Value 방식의 매개변수
void call_by_value( int_vac d)
{
int index;

for(index=0;index < 100;index++)
{
d.data

    = 0;
    }
    }

    // Call by Reference 방식의 매개변수
    void call_by_reference( int_vac* d )
    {
    int index;

    for(index=0;index < 100;index++)
    {
    d->data

      = 0;
      }

      }

      // Passing by Reference 방식의 매개변수
      void passing_by_reference( int_vac& d )
      {
      int index;

      for(index=0;index 꺽쇠 100;index++)
      {
      d.data

        = 0;
        }
        }

        int main()
        {
        int_vac a;

        a.data[1] = 2;
        call_by_value(a);
        printf("%d\n",a.data[1]);

        a.data[1] = 2;
        call_by_reference(&a);
        printf("%d\n",a.data[1]);

        a.data[1] = 2;
        passing_by_reference(a);
        printf("%d\n",a.data[1]);

        return 1;
        }

        보시면 아시겠지만 위의 세가지 함수 모두 같은 일을 합니다.

        int_vac라는 data배열을 갖은 스트럭처를 받아 함수로 넘겨 0으로 초기화

        하는 것입니다. 출력물은 아래와 같습니다.

        2
        0
        0

        처음과 두번째함수는 보아왔기 때문에 별 문제 없습니다.

        Call-by-Value : 중요한것을 매개변수안의 값(Value)만으로 보고 이를
        같은 크기의 양만큼의 스택메모리상에 복사 적재(팝)시키고
        함수안에서는 이 스택메모리상의 복사된 객체를 이용한다.
        함수 종료시 스택메모리에서 푸쉬를 하여 클리어한다.
        따라서 매개변수로 온 자체는 어떤 변화도 없다

        Call-by-Reference : 매개변수를 수정혹은 참조를 위한 실제 객체의 주소
        포인터를 얻어와서 이를 스택메모리상에 포인터변수로서
        넘어온 객체의 주소를 적재시키고 함수안에서는 스택상의
        주소를 이용해서 데이타 접근을 한다.
        함수 종료시 스택메모리상의 포인터변수를 푸쉬클리어한다.
        따라서 매개변수로 온 포인터 변수를 통해 실제 객체에 변화
        가 있을수 있다.

        Passing-by-Reference : 매개변수를 참조자로 썼기때문에 매개변수 실제 객체
        는 곧 매개변수와 같다. 따라서 스택메모리상에 아무것도 복
        사,팝 하지 않으므로 메모리 낭비가 없으며 효율적이다.
        함수안에서 매개변수 이용은 곧 실제 객체 이용이다.
        함수 종료시 스택메모리상에 올리지 않았기에 매개변수에 의
        한 푸쉬가 없다. 이또한 매개변수가 실객체와 같으므로 실객
        체의 변화가 있을수 있다.

        이상하네글이 다안타나나...


        ----------------------------------------------------------------------------

        ㅡ,.ㅡ;;의 이미지

        그리고 위와같이 C++에서 참조 연산자를 사용한다 하더라도..
        실제로 내부적으로는 주소복사가 이루어지지 않나요?

        그러니까 겉으로 보이기에는 Direct 같이 보이지만
        실제로 내부적으로 주소가 복사되지 않고는 힘들꺼 같은데..

        어디서 보기에 주소복사가되고 단지 이름만써도 그내용을 지칭하도록되어 있다고 하던데..


        ----------------------------------------------------------------------------

        alwaysN00b의 이미지

        흠.. 윗글은

        C 와 C++ 에서 call by reference 와 passing by reference 를 설명해 놓을 글이네요.

        제가 궁금한건

        진정한 개념의 call by reference와 passing by reference의 차이입니다.

        C는 함수가 호출되고 리턴될때 스택을 정리하지 않습니다.
        C++은 정리가 가능하죠.

        그럼 윗글의 call by reference와 passing by reference 의 차이에서
        스택을 정리한다는 점을 빼고 객체를 핸들링 할수 있다는건 똑같지 않나요?

        물론 사용방법이 틀리지만요.

        ps. passing by value 와 call by value 의 차이점은 무엇인지요?

        언제나 시작

        hurricanepark의 이미지

        c에서는 레퍼런스가 없다는게 무슨 뜻인가요?
        프로그래머에게 느끼게만 해준다는 의미로 말씀하신것 같은데 궁굼해집니다.

        오늘 하루두 즐거운 하루였으면 좋겠습니다.

        pizza1977의 이미지

        가 없나요??? 궁금하네요...

        포탈이는 불사신

        -------------
        포탈이는 불사신

        alwaysN00b의 이미지

        위 코드는 생각나는대로 대충 적은 것이고,

        func에서 *a 를 받아

        메모리를 할당한후

        확인해 보시면 처음 a값 그대로 일것입니다.

        즉 *a 가 받는 값은 해당 인자의 주소값을 복사해 오는 것입니다.

        그 주소값을 아무리 수정한다해도 원래 변수의 주소는 변하지 않습니다.

        설명이 좀 이상하네요 ..쩝.. 내공이 부족해서..

        main(){
           char *a;
           a = NULL;
         
           foo1(a);
         
           if( a == NULL ) printf(" a is NULL \n");
        }
         
        void foo1(char *a){
            a = malloc(BUFSIZ);
        }

        언제나 시작

        canelia04의 이미지

        call by reference 가 안될거 같은데..

        void func1(int *p) { }
        void func2(int x) { }

        컴파일 해보면 두 함수 모두 같습니다..

        C의 포인터는 단지 특정 메모리의 주소를 정수형태와 동일하게 넘길 뿐이죠
        접근 방법에 따라 차이가 있을 뿐...

        int x;
        scanf("%d", &x);
         
        x = (int)&x;
        scanf("%d", x);

        두개 결과가 모두 같다고 보셔두 이해하기 편하겠네요
        위에껀 call by reference 구 아래껀 call by value?
        제가 보기엔 둘다 value 같은데.. 뭐 사람마다 생각은 다르겠지만요

        IDNed의 이미지

        그것보다 질문중에 malloc은 size_t가 인자 아닌가요 -_-

        canelia04의 이미지

        void *malloc( size_t size );

        흠.. malloc(strlen("foo") + 1) 정도로 수정해야 할듯..

        canelia04의 이미지

        어쩌면 overloaded function 이 아닐까요 -_-;

        void* malloc(const char *str) {
            size_t len = strlen(str);
            return malloc(len + 1);
        }
        alwaysN00b의 이미지

        그냥 끄적이다 그렇게 되버렸네요 :)

        ㅡ,.ㅡ 님은 아직 답변이 없으시네요.. 쩝..

        언제나 시작

        steve24l의 이미지

        call by 레퍼런스
        pass by 레퍼런스(passing by 레퍼런스 보다 이게 맞지 않을까요?)
        이 두개의 차이가 뭔지는 잘 모르겠는데요...들어본적두 없구...
        C언어에서는 call by 레퍼런스가 없구요(확실함. C++에서 새로나온 기능중에 포함되어 있습니다)
        기본적으로 C,C++컴파일러에서는
        C라고 C코드를 짜도 C++문법이 적용이 되기때문에
        똑같은 결과가 나온건 아닌지...(제 추측;)
        그리고
        일단 제가 알기로 **는 포인터의 포인터를 갖고 있는 변수 있니다
        저도 실제로 사용해본적은 있어서 잘 모르지만
        넘어오는 a는 물론 문자열이겠고
        함수를 call할때 인자가 몇개인지 모르는 경우(main함수나 ,printf등)
        **이렇게 써줘서 인자가 몇개인지 상관없이 입력이 가능하게 해준다는군요
        그리고 call by 레퍼런스란 그냥 call by 발류는 엄연히 틀립니다.

        void func1(int *p) { }
        void func2(int x) { }

        이 두 함수가 같다고 하셨는데 사실 이 함수를 적어주실때
        void func1(int &p) { }
        라고 적으실껄 잘못적으신것 같구요
        call by 레퍼런스와 그냥 call by 발류의 차이점은요
        함수 내에서 봤을땐 똑같습니다.
        그런데 내부적으로는
        call by value를 했을경우
        함수를 호출할때 인자로 넘겨준 변수를 복사를 해서
        새로운 변수를 만들어 냅니다.
        그러나
        call by 레퍼런스를 했을경우
        함수를 호출할때 인자로 넘겨준 변수의 메모리를 보내주고
        그 함수에서는 그 메모리의 값을 참조해서 씁니다
        그렇기 때문에
        두 가지가 같아 보이는 이유구요(포인터와 비교되니까)
        실제로 const int &등
        콘스트형 레퍼런스를 쓰는 경우가 많은데
        이경우에는 주로 배열을 넘겨주거나
        굉장히 많이 호출되는경우에 씁니다
        const int형으로 선언해서
        call by value로 했을경우에
        원래 있던 변수에서 새로운 변수로 복사하는 작업이 오래 걸리기 때문에
        call by 레퍼런스로 해주고
        const형으로 선언해서 복사하는 시간을 절약하기 위함이지요
        제가 뭔가 잘못알고 있는부분이 있으면
        가르쳐 주시구요
        제 부족한 지식이 조금이나마 도움이 되었으면 좋겠습니다^^

        steve24l의 이미지

        아 그리구요 죄송하지만
        제가 kldp에 아는분이 한분도 없습니다^^;
        별로 오지도 않았고
        아이디도 자주 바꾸는데다가
        인터넷상에서 주위사람들과 친해지기가 힘들더군요
        나중에 또 보시게 되면 가끔 아는척도 좀 해주시구요
        제가 리눅스는 한번도 사용해본적이 없어서
        지금 겨우겨우 젠투 리눅스 설치만 해놓고
        아무것도 못하고 있습니다 ㅠㅜ
        도움좀 주세요^^;

        사랑천사의 이미지

        읽으면 읽을 수록 햇깔리는 포인터! 흐흠...

        char *p; // p의 주소가 지정 되며
        char **p; // *p의 주소? 흐흠...
        /* 아닌 것 같죠??  어떻게 설명 해야 하는지 잘 모르겠군요... 흐흠 이거 참.
        어떻게 생각 해야 할 지... */
        // 알기로 **는 2차 포인터 아닌가요? 그래서 char **argv 하면 2차 배열 행태로 인자들을 쭈욱 받을 수 있는 걸로 아는데요. 누구님 말씀처럼...

        어렵습니다 으음.
        ----
        일어나라! 싸워라! 그리고 이겨라!
        다만!!! 의미 있는 것에 그 힘을!!!
        그 능력과 노력을!!!

        사람천사

        댓글 달기

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