29일차
--------------------------------------
포 인 터 , 배 열
---------------------------------------
---------------------------
--- 포인터 사용시 주의할 점.
int iNum = 10;
double * dpNum = &iNum; // Warning!
double dNum = 10.5;
int * ipNum = &dNum; // Warning!
같은 포인터 타입이기에 Error는 안나서 실행은 되지만
다른 자료형(실수, 정수)이므로 Warning입니다.
상황에 따라 어떤 오류가 발생할지는 모르니 잘못된 것입니다.
int * ipNum;
*ipNum = 1000; // Warning!
ipNum에 주소값도 정해져 있지 않은데 그 주소값에 저장된 값을 바꾸면
어떤 문제가 발생할지 모르니 이것도 잘못된 것. warning, 런타임 에러
int * ipNum = 1000;
*ipNum = 10;
ipNum에 1000번지를 넣었는데 1000번지가 어딘지 알고 넣었는지?
또 그 값을 변경도 시켰으니 Warning, 런타임 에러
int * ipNum1 = 0;
int * ipNum2 = NULL;
포인터는 NULL (0) 으로 초기화 값으로 주는게 좋다고 합니다.
그래서 아래 코드를 시험해 보니
#include <stdio.h>
int main()
{
int * ipNum = NULL;
*ipNum = 10;
return 0;
}
초기화 값을 뭘 주든 제대로된 주소가 아니면 런타임 오류가 납니다.
----------------
--- 포인터 연산
출력 화면
포인터를 연산할 경우 그 자료형 만큼 주소값이 움직입니다.
char * cpNum = 1000;
cpNum = cpNum + 2; => 1000 + 2 * 1byte => 1002 (2byte움직임)
int * ipNum = 2000;
ipNum = ipNum + 2; => 2000 + 2 * 4byte => 2008 (8byte움직임)
double * dpNum = 3000;
dpNum = dpNum + 2; => 3000 + 2 * 8byte => 3016 (16byte움직임)
-----------------------
--- *(ipNum+0) == arr[0]
배열도 포인터도 주소값을 저장하고 있어서
사용법도 비슷합니다. 그래서
*(ipNum+0) == arr[0] <-- 이 등식이 성립합니다.
ex)
int main()
{
int arr[3] = {11, 22, 33};
int * ptr = arr;
printf("arr[0] : %d \n", arr[0]);
printf("arr[1] : %d \n", arr[1]);
printf("arr[2] : %d \n", arr[2]);
printf("ptr[0] : %d \n", ptr[0]);
printf("ptr[1] : %d \n", ptr[1]);
printf("ptr[2] : %d \n", ptr[2]);
printf("*(arr + 0) : %d \n", *(arr + 0) );
printf("*(arr + 1) : %d \n", *(arr + 1) );
printf("*(arr + 2) : %d \n", *(arr + 2) );
printf("*(ptr + 0) : %d \n", *(ptr + 0) );
printf("*(ptr + 1) : %d \n", *(ptr + 1) );
printf("*(ptr + 2) : %d \n", *(ptr + 2) );
return 0;
}
출력 화면
*(ipNum+0) == arr[0] <-- 이 등식이 성립합니다.
------------------------------------
--- char str1[] = "My String";
char * str2 = "Your String"; 장단점
여기서 str2 포인터 변수는 스택에 변수를 가리키는게 아니라
소스에 저장된 Your String을 가리킨다는 것을 명심!
배열
메모리 더 먹음, 수정 가능.
포인터
메모리 4byte만 먹음, 수정 불가.
--- 포인트 배열
포인트 타입의 배열이다.
ex)
arr 배열에 0, 1, 2 주소에 각각 주소값이 저장되어 있습니다.
printf("%d \n", *arr[0] );
-> printf("%d \n", *0x1000 );
-> printf("%d \n", 10 );
이런 과정을 거치겠죠....
--- 함수의 인자로 배열로 받을 수 없다.
그래서 포인터로 받는다.
ex)
--- Call by Address, Call by Value
함수에 인수를 다룰 때 쓰는 방법.
- Call by Address : 주소를 넘겨 호출.
- Call by Value : 값을 넘겨 호출.
ex) 예제 소스
#include <stdio.h>
void CallByValue(int, int);
void CallByAddress(int *, int *);
int main()
{
int iNum1 = 10;
int iNum2 = 100;
CallByValue(iNum1, iNum2); // Call By Value
printf("CallByValue() -> %d %d \n", iNum1, iNum2);
CallByAddress(&iNum1, &iNum2); // Call By Address
printf("CallByAddress() -> %d %d \n", iNum1, iNum2);
return 0;
}
void CallByValue(int n1, int n2)
{
int iTemp;
iTemp = n1;
n1 = n2;
n2 = iTemp;
}
void CallByAddress(int * n1, int * n2)
{
int iTemp;
iTemp = *n1;
*n1 = *n2;
*n2 = iTemp;
}
출력 화면
CallByValue 는 말 그대로 main에 있는 변수의 값만
가져와 쓰기 때문에 CallByValue 에서 무슨 짓을 해도
main의 변수에 접근할 수 없다.
CallByAddress 는 말 그대로 main에 있는 변수의 주소값을
가져와 쓰기 때문에 CallByAddress 에서 무슨 짓이든
main의 변수에 접근할 수 있다.
'코스웨어 > 14년 스마트컨트롤러' 카테고리의 다른 글
2014 04.03 업무일지 이재우 출석번호 21번 (15) | 2014.04.03 |
---|---|
04.02 업무일지 [이경진 출석번호 20번) (16) | 2014.04.03 |
2014.03.31 오영주 교육보고 (14) | 2014.04.01 |
2014.03.28 오두환 교육보고 (20) | 2014.03.30 |
2014년 3월 26일 송근영[출석번호 15번] (19) | 2014.03.27 |
2014년 03월 25일 손병규[출석번호 14] (16) | 2014.03.25 |
2014년 3월 24일 서상우 업무일지[출석번호 13번] (18) | 2014.03.24 |
20140321 박영주 업무일지[12번] (16) | 2014.03.21 |