ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 내 포인터 정리
    Lang/C 2021. 11. 9. 19:55

    발단 :

    main에 들어오는 인자 공부하다가

    https://m.blog.naver.com/ccgito79/30158255308

     

    [C언어] main (int argc, char **argv )의 의미는 무엇인가?

    main 함수의 인수 void(or int) main(int argc, char *argv[], char *env[]) {  }  인수는 뒤에서부터 생략이...

    blog.naver.com

    여기에 있는 char**argv와 char*argv[]가 동일한 표현이라는 말이 이해가 안돼서

    (그전부터 char **argv가 잘 안와닿아서 도움이 되는 말이었음)

     

    ============================

    (1)

    코딩도장 : 포인터의 메모리 주소는 일반포인터에 저장할 수 없다. 이중 포인터에 저장해야함.

    변수가 담겨있는걸 가리킬 때 = 포인터변수

    포인터(주소)가 담겨있는 걸 가리킬때 = 이중포인터

     

    ============================

    변수이름(일단제외), 변수값, 주소값 뿐이다.

    @일반변수

    변수값 있다 : 변수값은 1바이트(char)를 차지하거나, 4바이트(int)를 차지하거나 하겠지

    자체주소값 있다 : &붙여

     

    @포인터

    변수값 있다 : 변수값은 일반변수의 주소

    자체주소값 있다 : &붙여

    *abc하면 일반변수의 변수값을 가리킴, 포인터가 뭔갈 가리키고 있으니까 변수값과 주소값 외에 다른 하나 더를 알 수 있음

     

    @이중포인터

    변수값 있다 : 변수값은 포인터의 주소(그 포인터도 뭔갈 가리키고 있어서 아래 애들이 나옴)

    자체주소값 있다 : &붙여

    *abc.

    **abc.

    ∴ 이중포인터 변수 하나로 6개를 다 표현할 수 있어(이렇게 모든 경우의 수 조감도 해보니까 확 오네 이 방식 딴데서 또 써먹자)

    머릿속에 그림 그려보면 메모리 어떤 한칸이 다른 한칸을 가리키고 있고, 걔도 다른걸 가리키고 있어.

    *로 가리킬 수 있다

     

    ============================

    일단 선언할 때

    char **arc; 하면

    arc = 가리키려는 메모리의 주소; 가 들어가게 되고 --포인터는 가리키려는 애네 주소가 들어가게 되고

    그럼 이 변수를 쓰면

    얘의 값 : arc(가리키려는 메모리의 주소)

    얘의 주소 : &arc

    가리키는 변수의 값 : *arc

    가리키는 변수의 주소 : 불가능 한 게 아니고 사실 얘가 arc잖아?

    가리키는 변수의 값(이 변수값은 주소)이 가리키는 변수의 값 : **arc

    가리키는 변수가                               가리키는 변수의 주소 : 불가능 한 게 아니고 사실 얘가 *arc잖아?

    6개중에 6개를 다 가리킬 수 있네

    ==

    그럼 배열 a[0] 는 같은 말로 *a이고 --cs50에서 그랬음

    근데 a[0]얘는 그냥 주소고, 그냥 메모리 한칸한칸의 주소를 나타내는거라고 생각하면 되겠다

    s[a]안의 숫자로 쉽게 메모리 바로 옆칸을 가리킬 수 있네??

     

    ============================

    그러므로 char **argv와 char *argv[]가 동일한 표현 인 이유는?

     --완전히 동일한 표현이라는 말은 아닌게 뒤에건 argv만 쓰면 argv[0]은 아니잖아?

     

    char argv : 일반 변수 선언

    char *argv : 포인터 변수 선언

    char **argv : 포인터 배열 선언?? 이 안에 들어가는 값은 어떤 주소인데 그게 주소가 있는 주소다

     -> 그러므로 *argv하면 주소가 나오겠지!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *(argv+1)하면 옆칸이 나오고!!!!!!!!!!!! 그건 argv[1]이고

     

    char *argv[]는 그냥 직관적으로도 *주소의 char[]배열 이라고 직관이 온다.

    선언할때 *하면 주소니까 배열안에 주소 넣으라고

     

    그럼 왜 포인터를 가리키는 게(char **argv) 주소의 배열(char *argv[])이야? 라는 말에 답하기

     

    일단 배열 = 포인터

     > *char[]는 주소가 가리키는 메모리안에 들어있는 값

     > **char도 *char가 가리키는 메모리 안에 들어있는 값 마찬가지지

    일단 char[]가 주소 그 자체고, 포인터다! =  *char, *(char+1)... 처럼

    = 하튼 주소다, 가리키는 공간의 주소값, +1하면 옆칸으로 가는 주소

     > 그리고 거기에 *를 앞에 놓으면 그 주소가 가리키는 값이 된다.

    그럼 *char[]는? char[]가 주소고, 그 주소가 가리키는 값임. 

     

    근데 여기서 변수가 일반변수인지 포인터변수인지가 나뉘지

    int scores[3]; --이렇게 선언했었는데

    score[0] = 72;

    score[1] = 73;

    score[2] = 33;

     > 일반변수배열이잖아! 여기서 포인터변수 배열일수가 있는거네

    int *scores[3];

    score[0] = 주소1;

    score[1] = 주소2;

    score[2] = 주소3;

    그럼 char **선언은? char는 포인터변수의 값데, 그 포인터변수가 갖고있는 주소에 있는 값임.

    (char **argv 선언하는거랑 변수 argv에서 **argv하는거랑 다른거 알지)

     

    **char를 선언하면 걔는 

    주소의 배열이라는 얘기는 일단 주소가 4바이트라고 치고

    "1바이트1바이트1바이트1바이트", "1바이트1바이트1바이트1바이트", "1바이트1바이트1바이트1바이트"....

    이건데

    각 문자열의 첫 부분 1바이트는 각각 주소가 있겠지

     

     

    int **char

    그걸 ++ 하면 그 다음 배열, 반복..

     

    (1)

    char *s;면

    s[0]랑

    *s랑 같은거잖아? --알려줬었지 cs50형이 컴퓨터가 알아서 해석한다고

    (2)

    *char[0]과 **char 가 같다는 얘기잖아?

    일단 둘다 주소를 가리키는 포인터의 변수라는 얘기

     

    ===

     

    그럼 char **v

    v++;하면 그 다음 배열 주소인가? 그러면 엄청 신기해지는데

    어 맞아 시험2 에 repeat_alpha(1) 부분 내가 풀었는데 처음에 v++하고 들어가는거 에서 v = v+2;하고 인자 두개 입력해봐 잘돼

    "abc" "de" "e"

    각각의 주소 문자열 안으로 해야 종단문자 안포함되니 문자열 안에선 1차이씩 남

    a, d, e의 주소가 있겠지 걔네만 저장한 배열이 있어

    v1, v2, v3이라고 하자 얘네 주소도 1씩 차이나!!

    머릿속에 그림을 그려 **v선언은

    변수              "abcd" "ef" "ghjk"

    포인터변수 : a의 주소값을 갖는다! +1하면 b의 주소, +1하면 c의 주소이다

    // e랑 f를 만나려면 저 주소로는 안되고(아닌가? 종단문자 하나있고 그 다음부턴가?)(그게 아니면. 배열이니 그 다음 변수가 하나 더 필요하고 거기는 e의 주소를 갖는다 이거 더하면 f나옴)

    포인터포인터변수 : 주소1 주소2 주소3 있을 때 주소1을 변수로 갖지만 메모리 한칸 뒤에 주소2, 그 뒤에 주소3임

    값은 a의 주소를 변수값으로 갖고있는 애의 주소

    앞에 * 붙이면 그 주소의 값이니까 새로운 주소가 아니고 a의주소, e의 주소, g의 주소야

    이렇게 3층 구성해서 칸에 하나씩 종단문자랑 넣고 각 포인터로 가리키는

     

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

    a[0] = *a잖아?

    *a선언이면 값이고 --배열이 주소가 아닐 수도 있네? a[]선언할 때 이게 주소라는건가

    **a선언이면 주소인데

     

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

    char *A = "abcd"; 하면

    char A[4];

    A[0] = a....bcd다넣기 랑 똑같은데

     

    각각의 a b c d의 주소는 A, A+1...

    A++하면 한칸씩 b를 가리키는 주소 이런식으로 한칸씩 움직임.

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

    char **s는 주소의 배열이다

    "abcd"    "efg"    "hijkl"가 있을 때 (종단문자는 있겠지)

    주소주소주소주소 주소주소주소 주소주소주소주소주소 : abcdefghijkl각각의 주소 12개 뿐이라고 일단 생각해봐

    주소주소주소 : 그 중에 a, e, h의 주소가 특별하다 *s하면 a의 주소가 나온다.

    왜?

    s는 포인터포인터인데

    *s는 포인터포인터가 가리키는 포인터변수의 값인데

    포인터변수의 값은 a의 주소니까.

    그 a의 주소를 +1할수도 있고

    다른 함수로 넘기면 char *c로 받게될텐데 그 함수 내에서 *c로 a라는 값을 지칭할 수가 있다 

    다른 함수로 안넘기면 **s로 a라는 값을 지칭할 수 있지 *(*s+1) 와 **(s+1)도 다르겠네 앞에건 b고 뒤에건 e지?

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

    배열의 배열인데 --나타내는건 a의주소인데 한칸씩 뒤로마다 bcd가 있다 는 뜻?

    abcd같은 1바이트 하나씩의 주소는 1씩 차이남

    저 배열("abcd")의 배열(3개)을 가리키는 포인터는 각각 a, e, h의 주소를 갖는다

    그럼

    char **v에서

    *v = v[0] = a의 주소

    *(v+1) = v[1] = e의 주소

    *(v+2) = v[2] = h의 주소

    인데

    v[0][1] 이 b고

     

    **v는 a

    **(v+1)는 e

    **(v+2)는 h?? 이렇게 얘네도 한칸씩 차이가 날까?? 그렇지않을까

    a의 주소를 저장하는 포인터변수

    e의 주소를 저장하는 포인터변수

    h의 주소를 저장하는 포인터변수

    어차피 얘도 배열이잖아

     

    =========================

    int **a는 주소의배열 왜냐??맨처음애 주소를 가리키면 그게곧 배열이잖아

     

    자료형마다 포인터라는 자료형이 따로있어 
    주소가 들어가
    &포인터만들기
    *포인터없애기

     

    주소에 대고 *를 하면 값을 얻을 수 있으니 포인터 주소에 *하면 변수주소고 거기에 또 *하면 변수값이나오는

     

    =========================

    결론 :

    " " 이런 문자열도 첫번째 애 주소잖아 "abcde"면 메모리 5칸에 abcde순서대로 넣은뒤 a의 주소인것

    , char[1]이런 배열도 주소 --아니?? char[1]는 *(char+1)이잖아 변수의 값일 수도 있어 이중포인터선언이면 주소겠지만

    포인터 = 문자열( != 배열 인듯)

    리턴char * : 주소, 변수를 가리키는 주소네

    리턴char ** : 주소, 주소(=문자열)를 가리키는 주소네

     

     

     

     

     

     

     

     

     

     

    'Lang > C' 카테고리의 다른 글

    모듈, 헤더파일, 라이브러리  (0) 2022.06.01
    비트연산자 코딩도장 등  (0) 2021.10.15
Designed by Tistory.