Notice
														
												
											
												
												
													Recent Posts
													
											
												
												
													Recent Comments
													
											
												
												
													Link
													
											
									| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | 
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | 
| 26 | 27 | 28 | 29 | 30 | 31 | 
													Tags
													
											
												
												- c
- 챗GPT
- webhacking
- mysql
- BOF
- hackthissite
- php
- deep learning
- 인공지능
- backend
- 딥러닝
- ChatGPT
- 러닝스칼라
- flask
- BOF 원정대
- Javascript
- Python
- 백엔드
- 리눅스
- 웹해킹
- 러닝 스칼라
- hacking
- c++
- 경제
- Web
- hackerschool
- Linux
- 파이썬
- Shellcode
- Scala
													Archives
													
											
												
												- Today
- Total
jam 블로그
[C] 13. 포인터와 배열 본문
728x90
    
    
  반응형
    
    
    
  I. 포인터와 배열의 관계
- 배열의 이름은 무엇을 의미하는가? - 배열의 이름은 포인터다. 단 그 값을 바꿀수 없는 상수라는 점이 일반적인 포인터와의 유일한 차이점
 
#include <stdio.h>
int main()
{
    int a[5] = {0,1,2,3,4};
    printf("%d, %d\n",a[0],a[1]);
    printf("%d, %d\n",&a[0],&a[1]); 
    printf("배열이름 : %d\n",a);
    return 0;
}
- 위의 소스를 보면 처음의 printf는 a[0],a[1]의 값을 찍는거고 , 두번째 printf는 각각의 주소값을 세번째 printf는 배열이름에 대한 주소를 찍는다. - 결과를 보면 &a[0]와 a는 같다.
 
| 비교조건/비교대상 | 포인터 | 배열이름 | 
| 이름이 존재하는가? | Yes | Yes | 
| 이름은 무엇을 나타내는가? | 메모리의 주소 | 메모리의 주소 | 
| 변수인가? | Yes | No | 
| 상수인가? | No | Yes | 
- 포인터와 배열이름의 차이점은 배열이름이 상수이다보니 상관 없다. 따라서 상수 포인터라 한다.
#include <stdio.h>
int main()
{
    int a[5] = {0,1,2,3,4};
    int b = 10;
    a = &b;
}
- 마지막 줄 a는 상수 이므로 변수인 &b를 넣을수 없다.
- 1차원 배열이름의 포인터 타입 - int a[10] 이라면 int*형이다.
 
- 포인터를 배열의 이름처럼 사용할 수 있다.
#include <stdio.h>
int main()
{
    int arr[3] = {0,1,2};
    int *ptr;
    ptr = arr;
    printf("%d,%d,%d\n",ptr[0],ptr[1],ptr[2]);
    return 0;
}
- 위 소스처럼 arr를 포인터 처럼 써서 넘겨줄 수 있다.
II. 포인터 연산
- 포인터는 제한된 형태의 연산이 가능하다
#include <stdio.h>
int main()
{
    int *ptr = 0;
    char *ptr1 = 0;
    double *ptr2 = 0;
    printf("%d,%d,%d\n",ptr++,ptr1++,ptr2++);
    printf("%d,%d,%d\n",ptr,ptr1,ptr2);
    return 0;
}
- 먼저 ptr,ptr1,ptr2를 찍고 각각 하나씩 증가한다음 각 타입만큼 증가 시켜서 그다음번에 4,1,8을 찍는다. - 포인터 연산에 따른 실질적인 값의 변화는 포인터 타입에 따라 다르다.
 
#include <stdio.h>
int main()
{
    int arr[5] = {1,2,3,4,5};
    int *parr = arr;
    printf("%d\n",*parr);
    printf("%d\n",*(++parr));
    printf("%d\n",*(++parr));
    printf("%d\n",*(parr+1));
    printf("%d\n",*(parr+2));
    return 0;
}
- 위의 소스를 보면 *(parr+1) 같은것이 보인다. - 잘 생각해보면 parr은 배열의 이름(즉 배열의 첫번째 주소값)이 들어가있다. 거기에 +n 을 하면 더한만큼의 배열을 가리킨다.
 
- 중요한 결론! arr[i] = *(arr+i) 
III. 문자열 상수를 가리키는 포인터
- 문자열 표현 방식의 이해 
- 변수로 표현하는 방법 : char str1[5] = "ABCD";
- 상수로 표현하는 방법 : char *str2 = "abcd;
 
#include <stdio.h>
int main()
{
    char str1[5] = "abcd";
    char *str2 = "ABCD";
    printf("%s\n",str1);
    printf("%s\n",str2);
    str1[0] = 'x';
    str2[0] = 'x';
    printf("%s\n",str1);
    printf("%s\n",str2);
    return 0;
}
- 위의 소스는 컴파일은 잘된다 하지만 실행시 오류가 난다 어디서 날까? - str2[0] = 'x'; 이것이 잘못 된 것이다. 왜냐하면 str2는 문자열 상수를 변경하려고 하기 때문이다.
 
- 문자열 상수에 대한 조금 더 깊은 이해 - 문자열 상수는 메모리 공간에 할당되면 주소를 반환한다.
 
- 똑같은 문자열을 선언하면 한번만 메모리 공간에 할당된다.
#include <stdio.h>
int main()
{
    char *str1 = "ABCD";
    char *str2 = "ABCD";
    printf("%d,%d\n",str1,str2);
    return 0;
}
- 좋은 컴파일러는 똑같은 코드라 할지라도 메모리를 효율적으로 사용하기위해서 최적화를 한다.
IV. 배열 요소로 포인터를 지니는 포인터 배열
- 포인터 배열의 이해
#include <stdio.h>
int main()
{
    int a = 10, b= 20, c = 30;
    int* arr[3]={&a,&b,&c};
    printf("%d\n\",*arr[0]);
    printf("%d\n\",*arr[1]);
    printf("%d\n\",*arr[2]);
    return 0;
}
반응형
    
    
    
  '개발 및 관련 자료 > C' 카테고리의 다른 글
| [C] 16. 다차원 배열 (0) | 2013.05.12 | 
|---|---|
| [C] 14. 포인터와 함수에 대한 이해 (0) | 2013.05.12 | 
| [C] 12. 포인터의 이해 (0) | 2013.05.12 | 
| [C] 11. 1차원 배열 (0) | 2013.05.12 | 
| [C/C++] visual studio 2010 에서 계속하려면 아무 키나 누르십시오 가 뜨지 않을 경우 (0) | 2011.12.10 | 
			  Comments