1. 기본적인 개념

1.1 배열
데이터를 저장할 수 있는 공간이 나란히 나열 되어 있는 변수. 포인터로도 사용될 수 있는 변수.

1.2 포인터
포인터란 메모리의 주소값을 저장하는 변수다. 또는 주소값을 가리키는 변수다.

1.3 포인터 배열
주소값을 저장할 수 있는 공간이 나란히 나열 되어 있는 변수.



2. 특징

1.1 배열
배열의 길이는 only 상수
ex) arr[n] -> X, arr[7] -> O

문자열 변수를 만들 수 있다.
ex) arr[] = "strawberry";
문자열에 있는 알파뱃을 배열에 저장하여 각 알파뱃을 변경할 수 있다. arr[] = "good morning!" 과 같이 공백이 있어서는 안된다. printf로 찍어내는 것은 가능할 지라도(한번 해 볼 것) scanf로 입력 받는 것은 못 한다. scanf 는 공백을 기준으로 데이터 수를 결정짓는다.


1.2 포인터
* 연산자
  • 포인터 선언을 할때 사용.
  • 같은 포인터 끼리 주소값을 대입할 때는 다른 연산자가 필요없다.
  • 한 포인터 변수 안에 있는 주소값에 해당하는 일반 변수의 데이터를 찾아가는 역할
    int i = 100;
    int & pI;
    pI = &i; i 라는 변수의 주소값을 pI 포인터에 대입한다.
    *pI = 10; pI 의 변수에 저장되어 있는 주소값을 찾아간다(변수 i 가 저장되어 있음). 변수 i 의 값을 10으로 치환시킨다.

& 연산자
  • 같은 포인터끼리는 주소값을 반환할 때 *을 사용하지 않는다. 사실 포인터도 변수이므로 포인터 변수 a에 있는 주소값을 포인터 b로 대입시킬 때 주소값을 반환한다는 것은 말 자체가 틀린 것이다.
    ex1) 포인터 끼리 주소값 대입.  pArr1 = pArr2; -> pArr2의 주소값을 pArr1으로 대입
    ex2) 포인터 안에 들어 있는 주소값의 변수 데이터 치환. *pArr1 =  *pArr2; -> pArr2의 주소값에 있는 데이터를 pArr1의 주소값에 대입
    ex3) 포인터에 일반 변수 주소값 반환.  pArr = &n ;  -> 변수 n의 주소값 pArr 에 반환.


3. 포인터와 배열 비교

3.1 배열을 포인터처럼 쓸 수 있는 변수라고 하였다. 배열의 이름과 배열의 방번호는 살짝 다른 의미를 갖는다. 배열의 이름은 포인터와 같은 주소값을 저장할 수 있는 상수이고(상수 포인터), 배열의 방번호는 일반 변수와 마찬가지로 데이터를 저장하는 곳이다.
arr[5] = {1,2,3,4,5}; -> 배열의 이름 : arr, 배열의 방 번호 : arr[0], arr[1], ~ , arr[4]
cf) 포인터와 배열의 이름의 차이점은 포인터 변수의 주소값은 바꿀 수 있지만(변수) 배열 이름의 주소값은 바꿀 수 없다.(상수)

int arr[5] = {1,2,3,4,5};
printf("%d %d \n", arr[0], arr[1]); -> 1 2
printf("%d %d \n", &arr[0], &arr[1]); -> 1234567   1234571
return 0;

int a[5];
int *pA;
pA = a; -> pA와 a는 둘다 포인터로 &연산이 필요없다.
pA = &a[0]; -> pA는 포인터, a[0]는 일반 변수로 &연산이 필요하다.

3.2 포인터를 배열의 이름처럼 사용 가능.
배열 이름이 상수 포인터라고 하였다. 즉 주소가 정해져 있는 것이다. 주소는 첫번째 배열의 주소로 시작하고 변수타입에 맞게 다음 배열의 주소가 정해진다. 따라서 포인터가 배열 이림의 주소값을 받으면 저절로 다음 포인터의 주소가 정해진다.
int a[2];
printf("%d %d", *a[0], &a[1]);  -> 11100  11104     int에 맞게 4만큼 증가하였다.


int a[5] = {0,1,2,3,4};
int *pA;
pA = a;
printf("%d %d %d %d %d", pA[0], ~ , pA[4]); -> 0 1 2 3 4


3.3 문자열 상수를 가리키는 포인터
문자열을 저장시킬 때 두 가지 방법이 있다.(사실 더 있는데 그것은 나중에) 한 가지는 배열을 사용하는 것이고 다른 하나는 포인터를 사용한다. 배열을 사용하면 문자열 변수가 되고 포인터를 사용하면 문자열 상수가 된다. 

char str1[5] = "abcd"; ->  a b c d \0
  str[0] str[1]  str[2] str[3] str[4]
char str2 = "ABCD"; -> 포인터 str2 가 ABCD\0 을 가리킨다.

str[5]는 문자열을 수정할 수 있지만 str2 는 문자열을 수정할 수 없다. 그저 문자열을 가리키고만 있는 것

이상한점.
char *pA = 10; (10 이 데이터라고 생각할 것)
char *pB = 100; (100 이 주소값이라고 생각할 것)
둘 다 잘못 됐다. pA는 데이터의 값을 어디다(어느 주소) 저장해야 될지 모르므로 잘못됐고 pB는 100 이라는 주소값이 어디를 가리키고 있는 지 모르기 때문이다. 그런데 위 예문에는 char *str2 = "ABCD"; 로 되어 있다. 바로 위 예문과 똑같이 적용하면 오류가 떠야 하지만 정상 작동한다. 그 이유는 '문자열 상수는 메모리 공간에 저장이 되면, 그 순간에 문자열 상수의 주소값이 반환된다' 이기 때문.



'Language > C언어' 카테고리의 다른 글

컴파일과 링크의 차이  (0) 2013.10.23
라이브러리와 헤더파일의 차이  (0) 2013.10.23
잘못된 포인터의 사용 1  (0) 2013.10.23
코드 최적화  (0) 2013.10.23
컴파일이란  (0) 2013.10.23
Posted by 나무길 :