1.char * word = "hello" 이렇게되있을때, char * word = 0x12 이런식으로,

문자열의 주소값을 가지고있다고 생각해서 제가 이름값만 바로 넘겨버렸었거든요;
문자열의 주소값을 바탕으로 포인터로 접근하면 된다고생각했는데 안되더라구요 ㅠㅠ. 왜그런건가요 ㅠㅠ.? 왜, 문자열의 주소값이 아니라, 문자열을 가리키고있는 포인터의 주소를 이중포인터로 받아서 접근해야하는건가요??

 

 

2.배열의 경우엔 이름이 주소값이라서 저렇게 넘겨졌구요; 제가 개념이 꼬인거같은데 이부분 조금만 설명해주시면안될까요 ..?
c언어에서 문자열을 표현할때, 포인터로 표현할때와 배열의 표현할때 차이점을요 ㅠㅠ.



   테스트를 위하여, 문자열 연산을 싱글 포인터로 바꿔봤습니다. 
 



#include  
#include 
#include 
#include 
#include 

#define DICTIONARY_SIZE 30 
//단어를 랜덤으로 하나 고름 
void PickUpProblem(char *words[], char *word2);
//문제를 만들어냄( ex> apple -> _____) 
void MakeProblem(char * answer, char ** word);


int main(void)
{
    char * words[] = { "apple","banana","carrot","dog","egg","flash","inheritance","multimedia","console","printf",
        "best","initialization","constructor","structure","file","software","hardware","animal","zoo","vaccine",
        "matlab","cat","architect","toeic","computer","java","watch","samsung","brand","vitamin" };
    char * word = NULL;
    char answer[20];

    //단어를 랜덤으로 하나 고름 
    PickUpProblem(words, word);

    //고른 단어를 바탕으로 문제 제작 
    MakeProblem(answer, &word);

    return 0;
}

void PickUpProblem(char * words[], char * word2)
{
    int i;
    srand(time(NULL));
    word2 = words[rand() % DICTIONARY_SIZE];
}
void MakeProblem(char *answer, char **word)
{
    int i;

    for (i = 0; i < strlen(*word); i++)
    {
        answer[i] = '_';
    }

    answer[i] = '\0'; //문자열의 끝을 나타내는 널문자 삽입 
}

 

 해설 : 함수 인자는 Call by Value로 넘어갑니다. 

 
PickUpProblem() 함수의 인자인 word2 는 PickUpProblem() 함수의 "지역변수" 입니다. 즉, 함수가 끝나면 이 변수는 사라집니다. 휘발성입니다.

○ Main() 함수에서 PickUpProblem() 함수를 부르면서, main() 함수의 지역변수인 word 를 인자로 넘겼습니다. 하지만, word 변수 자체를 넘긴 것이 아니라, word 함수의 주소값만 넘긴 것입니다. "값" 만 넘긴 것입니다. (Call by Value)

○ 다음은 디버거를 이용하여, word와 word2 의 메모리 주소와, 그 값이 변하는 것을 찍어본 것입니다.


1. Main() 에서 PickUpProblem() 함수를 불렀을 때 입니다. word2 변수는 아직 호출되지 않아서 알 수 없습니다.NULL로 초기화 되어 있는 상태입니다.


2. PickUpProblem() 함수 안으로 들어와서 함수 실행이 막 끝난 상태입니다.



이 때, 메모리를 열어보면, word 변수는 변화가 없습니다.

처음에 PickUpProblem() 함수가 실행되었을 때, word2에다 word 변수의 메모리 주소만 적어놓은 것이기 때문입니다.

word2 = words[] 의 값을 할당하면서, 적어놓은 메모리 주소는 지워지고, 그 위에 "vaccine" 에 해당하는 주소가 저장됩니다.




이후, PickUpProblem() 함수 실행이 끝나면 word2 변수는 지역 변수이기 때문에 날아갑니다. 원래 main() 함수의 word 변수는 아무런 변화가 없습니다.



 

 이중 포인터를 쓰는 이유  

 
○ 문자열의 경우는, Char *word 를 문자열을 저장하는 하나의 변수로 생각하는 편이 이해가 쉽습니다. 즉, int A; 처럼 String word 를 선언한 것입니다. 즉, String = char* 인 것이죠.

그럼, String word의 참조를 함수의 인자로 전달하기 위해서는 String *word 를 전달해야 합니다.

○ String = char* 라고 했으니, 다시 치환하면 char **word 가 됩니다. 이해가 되실까요? 이걸 이해하면 포인터를 진짜로 이해한 것입니다.



 

 컴퓨터 메모리의 주소와 값을 구분해서 이해할 수 있어야 합니다.  이부분이 제일 어렵습니다

 
○ 다른 방식으로 풀 수도 있습니다. 위에 예제에서, word 변수의 주소값을 인자로 넘겼습니다. 위 예제에서는 이 주소값을 활용하지 않았습니다. 

○ strcpy(word2, words[rand()%DICTIONARY_SIZE])를 호출하면 문제가 해결됩니다. word2의 주소에다 words[]의 문자열 (여기서는 vaccine) 를 직접 써넣는 함수 입니다. 이중 포인터를 쓰는 것에 비하면 값을 카피하는 시간이 걸리기 때문에 비효율적입니다.



Posted by 지그프리드 지그프리드

BLOG main image
일상, 프로그래밍, IT 그리고 직장생활, Dive, 여행 by 지그프리드

카테고리

Class List (402)
Studies (30)
Exercise & Quizz (10)
Term Project (0)
ECIM list (Help!) (10)
Issues & News (0)
Gossip about IT & Job (22)
Tools (2)
Think about the Justice (23)
Book Review (170)
조엘 온 소프트웨어(번역) (28)
Diary (87)
Vacations (9)
Clash of clans 클래시 오브.. (11)

글 보관함

달력

«   2019/06   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
Total : 313,389
Today : 12 Yesterday : 11