목록프로그래밍 언어/C (9)
나의 지식 보관소
MinGW 깔고 환경변수 설정은 되어있다고 전제한다. C언어 확장을 다운받고 설정에서 System Include Path에 setting.json을 들어간다. 다음과 같이 아래 텍스트를 추가한다. "C_Cpp.default.compilerPath": "C:\\MinGW\\bin\\g++.exe", "miDebuggerPath": "C:\\MinGW\\bin\\g++.exe" Terminal->Cofigure Default Build Task... 에 들어가서 gcc 를 선택해준다. 그 후 Run->Add Configuration...을 선택해준 후 GDB를 선택하고 gcc를 선택해준다 그럼 끝이 아니라 디버깅 관련 정보를 담고 있는 launch.json 파일의 "configurations" 하위의 "ex..
아래와 같은 포인터를 void형 포인터라고 부른다. void *ptr void형 포인터에는 어떠한 주소값이든 담을 수 있다. 하지만 어떤 포인터 연산도 하지 못한다. 심지어 참조도 불가능하다.
함수 또한 변수처럼 메모리공간에 저장되는데, 함수포인터 변수는 이런 메모리상에 저장된 함수 주소 값을 저장하는 포인터변수를 말한다. 또한 배열의 이름이 배열의 시작지점 주소를 가리키듯이 함수의 이름은 함수가 저장된 메모리 공간의 주소 값을 의미한다. 그렇다면 함수이름의 포인터형은 어떤 기준으로 결정될까? 우리가 함수를 사용할때는 매개변수와 반환형 그리고 어떤 일을 하는지만 알면된다. 그마저도 함수가 어떤 일을 하는지 몰라도 작동은 가능하다. 즉 매개변수와 반환형 이 두가지 포인터형을 결정짓는다. 그러니 함수의 포인터 변수의 선언은 아래와 같이 하면된다. int (*funPtr) (float) //funPtr은 float형 매개변수 하나를 받고 int형을 반환하는 함수 포인터 매개 변수가 두개이상이면 다음..
2차원 배열의 이름이 가리키는 것은 2차원 배열 int arr2d[3][3]; 가 있다고 가정해보자. 배열의 이름인 arr2d가 가리키는 것은 첫 번째 요소의 주소이다. 또한 arr2d[0], arr2d[1], arr2d[2]은 각각 1행 2행 3행의 첫 번째 요소를 가리킨다. 그렇다면 arr2d와 arr2d[0]은 같은 것일까? 지닌 주소 값 자체는 같다. 하지만 arr2d와 arr2d[0]에 각각 sizeof연산을 해보면 arr2d는 36을 반환하는 것에 반해 arr2d[0]는 12를 반환한다. 즉 배열 이름인 arr2d는 배열 전체의 크기를 반환하였고 arr2d[0]은 1행의 크기를 반환한 것이다. 따라서 2차원 배열의 이름인 arr2d는 첫 번째 요소를 가리키면서 배열 전체를 의미하지만, arr2..
const는 Constant를 줄인 말로서 상수라는 의미이다. 즉 변수 선언 앞에 붙여 주면 해당 변수는 상수가되어 값의 변경이 금지 된다. 그런데 포인터 변수에서는 아래의 코드와 같이const를 붙이는 위치에 따라 그 역할이 조금 차이가 있다. const int* ptr1 = #//ptr1을 이용해 ptr1이 가리키는 변수에 저장된 값을 변경하는 것을 금지한다. int* const ptr2 = #//ptr2를 상수로 만들어 ptr2의 값을 변경하는 것을 금지한다. //1번줄과 2번줄을 합친형태도 가능하다. const int* const ptr3 = #//num에 저장된 값의 변경과 ptr3의 값을 변경하는것을 금지한다.
문자열을 선언하는 데에는 배열을 이용한 방법과 포인터를 이용한 방법 두 가지가 있다. char str1[] = "Hello World"; char* str2 = "Hello C"; 배열을 이용한 방법은 변수 형태의 문자열이다. 즉 문자열을 일부를 변경할수있다. 하지만 포인터를 이용한 문자열 선언은 상수 형태의 문자열이다. 즉 문자열의 내용의 변경이 불가능하다. 하지만 포인터를 이용한 문자열의 선언에서는 포인터가 다른 곳을 가리 킬 수 있다. 하지만 배열의 이름은 상수 형태의 포인터 변수이기 때문에 다른 곳을 가리키지는 못한다.
포인터 변수를 대상으로 +연산과 -연산을 할 수 있다. 중요한 것은 +1을 한다고 해서 간단히 1만 더해지지는 않는다는 것이다. int형 포인터에 1을 더하면 4가 증가하고 double형 포인터에 1을 더하면 8이 증가한다. 즉 간단히 말해서 type 형 포인터 변수에서의 n을 더한다는 것의 의미는 n*sizeof(type)의 크기만큼 더하겠다는 것과 같다. int arr[3] = { 1, 2, 3 }; printf("%d",*(arr+1));// printf("&d",arr[1]); 과 같은 결과가 나온다. 즉 int형 포인터의 경우 +1을 하면 4파이트 떨어진 메모리를 가리키게 되므로 배열에서 다음 요소를 가리키게 된다. 따라서 arr[i]과 *(arr+i)는 같다!
우리가 흔히 사용하는 배열의 이름은 포인터 상수이다. 말 그대로 값을 바꿀 수 없는 포인터이다. 그렇다면 배열의 이름은 어디를 가리킬까? 배열의 이름이 가리키는것은 배열의 시작 주소 값이며, 이는 배열의 첫 번째 요소의 주소 값과도 같다. 앞서 말한 내용을 종합해보면 포인터와 배열은 상수이냐 변수이냐의 차이외에는 같다는 것을 알 수 있다. 따라서 배열에 *연산을 할 수 있고 반대로 포인터에 [ ] 연산을 할 수 있다. int arr[3] = { 1, 2, 3 }; int* ptr = arr; print("%d",ptr[1]); 따라서 이러한 활용도 가능하다.