-
발단 :
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