C lang

[C language] Geany편집기 - 10. 포인터를 가리키는 포인터, puts, fputs, Dynamic Memory (동적 메모리 할당)

걍작 2022. 3. 27. 19:30

#정리

#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개는 쓰레기 값이 들어온 것이다. 

(우) 앞의 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;
}