[C language] Geany편집기 - 10. 포인터를 가리키는 포인터, puts, fputs, Dynamic Memory (동적 메모리 할당)
#정리
#pointer - pointer - 포인터의 주소값을 가리키는 포인터
//주소 값도 값이기 때문에 그 값을 가리키는 포인터를 만들 수 있다.
- 포인터의 실제 주소 값은 계속 달라지지만, 참조한 수만큼 역참조하면 결국 같은 값을 가리킨다.
- 모든 포인터 변수는 역참조를 통해 값에 접근하여 수정할 수 있다.
//인수이름이 중요한 것이 아니라 *의 갯수가 중요하다.
- void test02(char **ppt);
#pointer_pointer_multi - 배열 포인터의 주소를 가리키는 포인터 변수
//배열을 가리키는 포인터를 만드는 방법이 두 가지가 있다.
- 1. 3개의 원소를 가진 배열을 가리키는 포인트 변수 생성
- 2. arrs의 시작 주소 값을 가리키는 포인트 변수 생성
//2번 방법을 중복하여, 포인트 변수를 가리키는 포인트 변수를 만들 수 있다.
- int **ppt_arrs = (int**)arrs;
//중복 캐스팅 된 포인트 변수의 값을 다시 불러올 때는 값을 도출할 때도 (int *)캐스팅을 통해 연산 결과 값의 타입을 맞춰줘야 한다.
- printf("test02 %d\n",*((int *)ppt_arrs+ x));
#other output - 출력 명령문
//puts, fputs 명령어로도 값을 출력할 수 있다.
- puts : 자동으로 엔터가 들어감.
- fputs : stdout 옵션이 들어가야하며, 자동 엔터 기능이 없음.
#Dynamic Memory - 동적 메모리 할당
//(pt_arr 변수)동적 메모리 할당(주소 생성) 및 값 초기화 {0,0,0,...,0,0}
- pt_arr = malloc(sizeof(int)*10); ~free(pt_arr) - pt_arr = calloc(10,sizeof(int)); ~free(pt_arr)//10개 값 초기화
//(pt_arr 변수) 메모리 할당 사이즈 "변경" 및 초기화 {0,0,0,...,0,0}
- 기존에 메모리에 할당된 변수가 있어야 한다. - pt_arr = realloc(pt_arr,sizeof(int)*5); //할당 사이즈 5개로 변경 및 값 초기화
>> 예문) 앞의 0 다섯개는 초기화 된 값, 뒤에 5개는 쓰레기 값이 들어온 것이다.
#pointer - pointer - 포인터의 주소값을 가리키는 포인터
//주소 값도 값이기 때문에 그 값을 가리키는 포인터를 만들 수 있다.
- 포인터의 실제 주소 값은 계속 달라지지만, 참조한 수만큼 역참조하면 결국 같은 값을 가리킨다.
- 모든 포인터 변수는 역참조를 통해 값에 접근하여 수정할 수 있다.
//인수이름이 중요한 것이 아니라 *의 갯수가 중요하다.
- void test02(char **ppt);
--예문 코드 보기--
#include <stdio.h>
void test01(int **ppt);
void test02(char **ppt);//인수이름이 중요한 것이 아니라 *의 갯수가 중요하다.
int main(int argc, char **argv)
{
printf("pointer pointer...\n");
int x=10;
int *pt = &x;
int **ppt = &pt;//포인터 변수의 주소값을 포인터 변수에 다시 넣는다.
int ***pppt = &ppt;//포인터에 포인터를 계속 씌울 수 있다.
printf("---address-----\n");
//포인터의 주소 값은 계속 달라지지만, 참조한 수만큼 역참조하면 결국 같은 값을 가리킨다.
printf("x address: %p\n",&x);
printf("pt address: %p\n",pt);
printf("*ppt address: %p\n",*ppt);//ppt의 주소는 다르지만 *을 이용해 pt를 불러온 것이다.
printf("**pppt address: %p\n",**pppt);
printf("ppt address: %p\n",ppt);//실제 변수의 주소는 달라진다.
printf("pppt address: %p\n",pppt);
printf("---value-----\n");
//모든 포인터 변수는 역참조를 통해 값에 접근하여 수정할 수 있다.
x=33;// x의 값을 변경 했기 때문에, 아래 값이 다 바뀐다.
printf("x value: %d\n",x);
printf("pt value: %d\n",*pt);
printf("**ppt value: %d\n",**ppt);
printf("---value-----\n");
*pt=99;// x주소값의 값을 변경 했기 때문에, 아래 값이 다 바뀐다.
printf("x value: %d\n",x);
printf("pt value: %d\n",*pt);
printf("**ppt value: %d\n",**ppt);
printf("---value-----\n");
**ppt=100;// x주소값의 값을 변경 했기 때문에, 아래 값이 다 바뀐다.
printf("x value: %d\n",x);
printf("pt value: %d\n",*pt);
printf("**ppt value: %d\n",**ppt);
printf("---value-----\n");
***pppt=1000;// x주소값의 값을 변경 했기 때문에, 아래 값이 다 바뀐다.
printf("x value: %d\n",x);
printf("pt value: %d\n",*pt);
printf("**ppt value: %d\n",**ppt);
printf("***pppt value: %d\n",***pppt);
char c = 'A';
char *pc = &c;
char **ppc = &pc;
char ***pppc = &ppc;
printf("***pppt value: %d %c\n",***pppc, ***pppc);
printf("---function-----\n");
test01(&pt);
test02(&pc);
return 0;
}
void test01(int **ppt){
printf("**ppt value: %d\n",**ppt);
}
void test02(char **ppt){
printf("**ppt value: %d %c\n",**ppt, **ppt);
}
#pointer_pointer_multi - 배열 포인터의 주소를 가리키는 포인터 변수
//배열을 가리키는 포인터를 만드는 방법이 두 가지가 있다.
- 1. 3개의 원소를 가진 배열을 가리키는 포인트 변수 생성
- 2. arrs의 시작 주소 값을 가리키는 포인트 변수 생성
//2번 방법을 중복하여, 포인트 변수를 가리키는 포인트 변수를 만들 수 있다.
- int **ppt_arrs = (int**)arrs;
//중복 캐스팅 된 포인트 변수의 값을 다시 불러올 때는 값을 도출할 때도 (int *)캐스팅을 통해 연산 결과 값의 타입을 맞춰줘야 한다.
- printf("test02 %d\n",*((int *)ppt_arrs+ x));
--예문 코드 보기--
#include <stdio.h>
#define ARR_ROW 2
#define ARR_COL 3
void test01(int *pt_arrs);
void test02(int **ppt_arrs);
int main(int argc, char **argv)
{
printf("pointer pointer...multi array\n");
int arrs[ARR_ROW][ARR_COL] = {{1,2,3},{4,5,6}};
//1. 3개의 원소를 가진 배열을 가리키는 포인트 변수 생성
int (*row)[3] = arrs;
printf("row address: %p\n", row);
//2. arrs의 시작 주소 값을 가리키는 포인트 변수 생성
int *pt_arrs = (int*)arrs;
printf("pt_arrs address: %p\n", pt_arrs);
int **ppt_arrs = (int**)arrs;
printf("ppt_arrs address: %p\n", ppt_arrs);
printf("--- function ---\n");
test01((int*)arrs);
test02((int**)arrs);
return 0;
}
void test01(int *pt_arrs){
for(int x=0;x<ARR_ROW*ARR_COL;x++){
printf("test01 %d\n",*(pt_arrs+ x));
}
}
void test02(int **ppt_arrs){
for(int x=0;x<ARR_ROW*ARR_COL;x++){
printf("test02 %d\n",*((int *)ppt_arrs+ x));//(int **)로 캐스팅된 포인터 이므로, 값을 도출할 때도 (int *)캐스팅을 통해 연산 결과 값의 타입을 맞춰줘야 한다.
}
}
#other output - 출력 명령문
//puts, fputs 명령어로도 값을 출력할 수 있다.
- puts : 자동으로 엔터가 들어감.
- fputs : stdout 옵션이 들어가야하며, 자동 엔터 기능이 없음.
--예문 코드 보기--
#include <stdio.h>
int main(int argc, char **argv)
{
printf("other output...\n");
char name[10] = "namekim";
printf("printf: %s\n",name);
//puts : 값 출력
puts(name);//자동으로 엔터가 들어감.
puts(name);
//fputs : stdout 옵션이 들어가야함.
fputs(name,stdout);//엔터 기능이 없음.
fputs(name,stdout);
fputs("\n",stdout);
return 0;
}
#Dynamic Memory - 동적 메모리 할당
//(pt_arr 변수)동적 메모리 할당(주소 생성) 및 값 초기화 {0,0,0,...,0,0}
- pt_arr = malloc(sizeof(int)*10); ~free(pt_arr)
- pt_arr = calloc(10,sizeof(int)); ~free(pt_arr)//10개 값 초기화
//(pt_arr 변수) 메모리 할당 사이즈 "변경" 및 초기화 {0,0,0,...,0,0}
- 기존에 메모리에 할당된 변수가 있어야 한다.
- pt_arr = realloc(pt_arr,sizeof(int)*5); //할당 사이즈 5개로 변경 및 값 초기화
>> 예문) 앞의 0 다섯개는 초기화 된 값, 뒤에 5개는 쓰레기 값이 들어온 것이다.
--예문 코드 보기--
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
printf("Dynamic memory...\n");
int arr[10];
int *pt_arr;
pt_arr = arr;
for(int i=0;i<10;i++){
arr[i] = i+1;
}
//pt_arr = malloc(sizeof(int)*10);//pt_arr 값 초기화 {0,0,0,...,0,0}
pt_arr = calloc(10,sizeof(int));
pt_arr = realloc(pt_arr,sizeof(int)*5); //update size
for(int i=0;i<10;i++){
printf("%d ",arr[i]);
}
printf("\n");
for(int i=0;i<10;i++){
printf("%d ",pt_arr[i]);
}
printf("\n");
free(pt_arr);
return 0;
}