// 문자열의 길이
#include <stdio.h>
int str_length(char *str);
int main() {
char word[] = "What's your name?";
printf("length : %d\n", str_length(word)); //포인터에 문자열 배열의 첫 주소를 던져준다
return 0;
}
int str_length(char *str) {
int i = 0;
while (str[i]) { // null 문자를 만날때까지 배열을 1씩 증가시킨다
i++;
}
return i;
}
// 함수 포인터
#include <stdio.h>
int max(int a, int b);
int donothing(int c, int k);
int main() {
int a, b;
int (*pfunc)(int, int); // 리턴형이 int 이고 두개의 int 인자를 가진 함수를 가리킨다
pfunc = max; // 함수의 주소값을 포인터에 넣어준다
scanf("%d %d", &a, &b);
printf("max(a,b) : %d\n", max(a, b));
printf("pfunc(a,b) : %d\n", pfunc(a, b));
pfunc = donothing;
printf("donothing(1,1) : %d\n", donothing(1, 1));
printf("pfunc(1,1) : %d\n", pfunc(1, 1));
return 0;
}
int max(int a, int b) {
if (a > b) return a;
else return b;
return 0;
}
int donothing(int c, int k) {
return 1;
}
// 배열을 함수의 인자로 받기
#include <stdio.h>
int add_number(int *parr);
int main() {
int arr[3];
int i;
for (i = 0; i < 3; i++) {
scanf("%d", &arr[i]);
}
add_number(arr);
printf("배열의 각 원소 : %d, %d, %d\n", arr[0], arr[1], arr[2]);
return 0;
}
int add_number(int *parr) {
int i;
for (i = 0; i < 3; i++) {
parr[i]++;
}
return 0;
}
// 함수에서 포인터의 활용
// 다른 함수에서 사용된 변수의 값을 바꾸는데 포인터를 활용할 수 있다
#include <stdio.h>
int change_val(int *pi) {
printf("----- change_val 함수 내부 -----\n");
printf("pi 의 값 : %p\n", pi);
printf("pi 가 가리키는 것의 값 : %d\n", *pi);
*pi = 3;
printf("----- change_val 함수 끝 -----\n");
return 0;
}
int main() {
int i = 0;
printf("i 변수의 주소값 : %p\n", &i);
printf("호출 이전 i 의 값 : %d\n", i);
change_val(&i);
printf("호출 이후 i 의 값 : %d\n", i);
return 0;
}
// 배열의 포인터
#include <stdio.h>
int main() {
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*parr)[3]; // 크기가 3 인 배열을 가리키는 포인터
// 배열의 한 행의 크기를 전달한다
// 2차원 배열에서의 배열의 이름도 배열의 첫번째 행을 가리키는
// 포인터로 형 변환 되며,
// 첫번째 행은 크기가 3인 1차원 배일이다.
parr = &arr; // parr 이 arrd 을 가리키게 한다.
printf("parr[1][2] : %d , arr[1][2] : %d\n", parr[1][2], arr[1][2]);
return 0;
}
잘못된 예
// 배열의 포인터 - 잘못된 예
#include <stdio.h>
int main() {
int arr[2][3];
int brr[10][3];
int crr[2][5];
int(*parr)[3];
parr = arr; // OK
parr = brr; // OK
parr = crr; // crr 의 첫번째 행의 크기가 3이 아니므로 잘못됨
return 0;
}
/ 배열 이름의 주소값
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
int (*parr)[3] = &arr; // 크기가 3 인 배열을 가리키는 포인터
// arr 이 크기가 3인 배열이므로 &arr을 보관할 포인터는 크기가 3인 배열을 가리키는
// 포인터가 되어야 한다.
// 괄호를 사용하지 않고 int *parr[3] 과 같이 사용하면 int* 원소 3개를 가지는
// 배열을 정의한 것으로 된다.
printf("arr[1] : %d\n", arr[1]);
printf("parr[1] : %d\n", (*parr)[1]);
return 0;
}
결과
arr[1] : 2
parr[1] : 2
arr 과 parr은 같은 주소(같은 값)을 가진다.
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
int (*parr)[3] = &arr;
printf("arr : %p\n", arr);
printf("parr : %p\n", parr);
return 0;
}
참고로, 아래 글은 M1 맥에서만 해당이 된다. github에서도 M1맥의 경우 몬터레이 베타버전을 사용하는 사용자에게서 이슈 되었으며, 인텔 맥에서는 확인된 바가 없다.
오늘(12/26) 새벽에 macOS Monterey 정식 버전이 릴리즈 되었다.
맥으로 밥 벌어먹는 직업은 아닌지라, 가벼운 마음으로 업데이트를 했다.
업데이트 후에도 라이트 유저라서 그런지 그다지 뭔가 바뀌었다는 느낌이 없다. 카탈리나에서 빅서로 넘어올때는 독 아이콘이라도 바뀌어서 뭔가 바뀌었다는 느낌이라도 있었는데.. 이건 시스템 창을 열어보기 전에는 바뀌었는지도 모르겠다.
문제는.. 저녁에 집에 와서 C 언어 공부를 하려고 할때 발생했다.
평소처럼 간단한 프로그램을 짜고 빌드를 하는데, 오류가 발생했다.
처음 보는 에러창이다.
몬터레이 설치되면서 뭔가 설정을 건드렸나 싶어 launch.json 파일을 다시 만들기도 하고, 잘못 입력된게 있나 싶어 여기 저기 뒤져보았지만 원인을 찾을수가 없었다.
검색에 검색을 더하여 github에서 <extension>/lldb/bin 폴더에 들어있는 debugserver executable을 삭제하라는 것 까진 찾았으나, 이게 뭔지 아무런 설명이 없었다. 심지어 저 폴더가 어디에 있는지도 전혀 알길이 없으니... 검색을 해 봐도 더 이상 나오는 게 없었다.
공부를 해야 하는데 포기할 수가 없어 github에서 연관되는 것들을 검색하다가, 홈 폴더에 .vscode 폴더가 숨어있는 것을 발견했다. 혹시나 하여 또 뒤지고 들어가다가 결국 발견했다.
홈 폴더 아래의 .vscode/extensions/vadimcn.vscode-lldb-1.6.8/lldb/bin 폴더 안에 있는 debugserver 라는 파일을 삭제하고나서 다시 vscode를 실행해 보니 잘 작동한다.
즉, <extension>/lldb/bin 폴더는 CodeLLDB extension에서 /lldb/bin 폴더를 의미하는 거였다. 이런걸 편집해 본 사람들은 무슨 말인지 금방 알겠지만, 나는 extension들이 홈 폴더 아래에 있는줄도 몰랐다.
macOS를 사용하기 시작한지 이제 1년 가까이 되어간다.
처음엔 거의 아무것도 모르는 상태였는데, 지금은 집에서는 맥을 매인 컴퓨터로 사용할 뿐만 아니라 빌드 환경까지 만들어놓고 공부를 하고 있다...
// 포인터의 시작
#include <stdio.h>
int main() {
int *p;
int a;
p = &a;
printf("포인터 p 에 들어 있는 값 : %p \n", p); // %p 는 포인터 값을 16진수로 출력한다
printf("int 변수 a 가 저장된 주소 : %p \n", &a); // & 단항 연산자는 a의 메모리 주소값을 불러온다
return 0;
}