학습 복습 내용은 아이티뱅크 C언어 I 강의와 교안을 바탕으로 합니다.
1. 포인터
* 정수 형태 메모리 주소 값을 저장하는 변수
int num = 7;
int *pnum; //포인터 변수 pnum의 선언
pnum = # //num의 주소값을 pnum에 저장
//num의 주소값은 0x12ff76등의 정수값으로 표현된다!
* 포인터 변수의 크기는 시스템의 주소 값 크기에 따라 다르다.
* 포인터 변수에 저장되는 값은 형태는 모두 동일하지만, 선언하는 방법엔 차이가 있다.
* int형 포인터 변수에는 int형 변수의 주소값만 저장이 된다.
* 포인터 연산을 통해 메모리 접근 기준을 세움
* 예제 - int형포인터 변수 통해 메모리(변수) 접근 시, 4바이트 메모리 공간에 부호 있는 정수 형태로 데이터를 읽고 쓴다.
int * pnum1;//int형 변수를 가리키는 포인터 변수 선언
int* pnum1;
int *pnum1; //이 세 가지는 모두 같은 표현
double *pnum2; //double형 변수를 가리키는 포인터 변수 선언
type *ptr; //type형 변수를 가리키는 포인터 변수 선언
* null값으로 포인터 변수 값을 초기화하는 것은 괜찮다.
* 포인터의 필요성!!
(1) 함수 내에서 함수 외부에 선언된 변수의 접근을 위해
(2) 메모리 동적 할당 등을 위해
(3) 자료구조에 유용하게 쓰임
2. 포인터 연산
* 배열, 혹은 문자열의 이름은 이들의 시작 주소값을 가리키는 포인터이다.
# 배열의 이름은 배열 시작 주소값을 의미한다
int arr[3] = {1, 2, 3};
# 포인터 변수 선언
int *ptr = &arr[0];
int *ptr2 = arr; // ptr과 ptr2는 같은 주소를 가리킴
# 배열 이름과 포인터 관계
arr[0] += 5; //6
ptr[0] += 2 //8
printf("%d %d %d \n", *ptr, *(ptr+1), *(ptr+2)); //8 2 3
# 포인터 type 따라 포인터 연산 결과 다름
double ptr3 = 0x0010;
printf("%p %p\n", ptr2, ptr3); // 00000020, 00000010
printf("%p %p\n", ptr2+1, ptr3+1); // 00000024, 00000018
> arr[i] == *(arr+i) 의 의미.
char str1[] = 'Hello';
char *str2 = 'Hello';
3. 포인터 배열
int *arr1[20];//길이가 20인 int형 포인터 배열 arr1
int num1 = 1, num2 = 2, num3 = 3;
int *arr[3] = {&num1, &num2, &num3};
char *strArr[3] = {'Simple', 'String', 'Array'};
* 활용 - 배열을 함수의 매개변수로 전달해줄 때는, 값만 복사해준다. 따라서 원본 배열을 다루려면 배열의 포인터를 매개변수로 전달해야 한다!
void ParamPtr(int *param)
//void ParamPtr(int param[]) 으로도 가능
{
printf("%d", param[0]);
}
int main(void)
{
int arr[3] = {1};
ParamPtr(arr);
return 0;
}
* 함수 호출 시,
(1) Call-by-value: 단순히 값을 전달
(2) Call-by-reference: 메모리에 접근할 수 있는 주소 값을 전달
4. 다차원 배열
* TYPE arr[세로길이][가로길이] 로 2차원 배열 선언
* 실제 메모리는 다차원 배열도 1차원 배열의 형태로 저장
* 2차원 배열 초기화 예제..
int arr[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int arr[3][3] = {
{1},
{4, 5},
{7, 8, 9}
};
int arr[3][3] = {1, 2, 3, 4, 5, 6, 7};
int arr[][4] = {1, 2, 3, 4, 5, 6, 7, 8};
int arr[][2] = {1, 2, 3, 4, 5, 6};
int arr[][] = {1, 2, 3, 4, 5, 6, 7, 8};//에러!!
5. 다중 포인터
int num = 5;
int *ptr = #
int **dptr = &ptr; //*(*dptr) = *(ptr) = &num!!
* 포인터 변수의 swap은 이중포인터를 이용해서 해야 한다.
void Swap(int **dp1,int **dp2)
{
int *temporary = *dp1;
*dp1 = *dp2;
*dp2 = *temporary;
}
int main(void)
{
int n1 = 1, n2 = 2;
int *ptr1 = &n1;
int *ptr2 = &n2;
Swap(&ptr1, &ptr2); //주소값 전달
printf("%d %d\n", *ptr1, *ptr2);//2 1
return 0;
}
6. 배열 포인터 변수
int arr[3][4]; //int형 변수고, sizeof(int)x4만큼 증가 혹은 감소하는 포인터형이 필요함!
int (*ptr)[4];
* 2차원 배열에서도
arr[i] == *(arr+i)는 적용됨
int arr[2][2] = {{1, 0}, {3, 2}};
arr[1][0]; //2
(*(arr+1))[0]; //2
*(arr[1]+0); //2
*(*(arr+1)+0);//2
7. 함수 포인터
int (*fptr) (int); //int를 받아 int를 반환하는 함수에 대한 포인터 변수
int SampleFunc(int num) { ... }
fptr = SampleFunc;
fptr(10);
8. 스트림
* 데이터가 한 방향으로 흐르는 경로를 스트림이라 함
* stdin - 표준 입력 스트림
* stdout - 표준 출력 스트림
* stderr - 표준 에러 스트림
9. EOF, 문자열 출력, 문자열 입력!
* EOF (End Of File) - 파일의 끝을 표현하기 위해 정의된 상수
* fgetc 혹은 getchar 함수 호출이 EOF 반환할 때 - 파일의 끝에 도달함
* 문자열 출력 함수 - puts, fputs
puts("hello");
fputs("hello", stdout); //모니터
* 문자열 입력 함수 - gets, fgets
fgets("hello!!", sizeof("hello!!"), stdin);
10. 입출력 버퍼
* 버퍼: 특정 크기의 메모리 공간
* 호출된 출력 함수가 반환될 때는 출력 버퍼로 데이터가 완전히 전송된 상태
* 엔터를 입력할 때가 키보드로 입력된 데이터가 입력버퍼로 전달되는 상태
* 출력버퍼를 '비운다' - 출력버퍼에 저장된 데이터를 목적지로 다 전송
fflush(stdout);
* 입력버퍼를 '비운다' - 입력버퍼에 저장된 데이터를 없앤다!
void ClearReadBuffer(void) {
while(getchar() != "\n");
}
'학점은행제' 카테고리의 다른 글
[네트워크] 학습복습 - 통신의 개념, 컴퓨터 네트워크 역사, OSI7계층 (0) | 2021.05.24 |
---|---|
[컴퓨터시스템] 학습복습 - 유닉스/리눅스, 커널, 시스템 호출 (0) | 2021.05.22 |
[C 언어 I] 학습복습 - printf, scanf함수, 반복문, 조건식, 함수, 지역변수, 전역변수, register, 재귀함수, 배열 (0) | 2021.05.22 |
FFT (Fast Fourier Transform) 정리 (0) | 2021.05.21 |
[C 언어 I] 학습복습 - C언어 개론, 변수, 연산자, 데이터 표현, 기본 자료형 (0) | 2021.05.20 |
댓글