본문 바로가기
C언어

C언어_포인터

by 히예네 2023. 1. 24.
728x90
반응형

1. 포인터(java에서는 레퍼런스)

데이터가 있는 위치(주소)를 통해 제어하는 문법

int a a라는 이름이 기억안나는데 어떻하지???

주소를 부르자! a 의 주소를 저장하는 특별한변수

이 주소에는 int형 자료가 있을꺼야

포인터 자체가 인트가 아니다 (포인터변수 포인터상수)

주소값을 가진 변수 주소값을 가진 상수 = 배열이름
  • 일반 변수 int a;

변수 : 상수, 한문자 등 데이터를 저장하는것

EX ) 10 (Data value)

무조건 4바이트

  • 포인터 변수 int* p;

데이터가 아닌 주소를 저장하는것

EX ) #12FF7C(주소)

무조건 8바이트(주소는 16자리) java도 8바이트로 동일

#include <stdio.h>

void main()
{
int a = 10;
int* p;  //포인터 변수. 주소를 저장함 16자리*4비트 = 64비트(컴퓨터의 가닥선수와 연관) 64비트=8바이트
p = &a; //포인터 변수 - a의 주소를 준 것이다, 주소를 저장하는 용도의 변수

printf(" %p \\n", &a);
printf(" %p \\n", p);

//p가 가진 주소안에 있는 데이터를 출력

printf("%d \\n", p);//p가 가르키는 값 (a의 주소)
printf("%d \\n",*p); //p가 가르키는 곳의 값

double b = 3.14;
double* p2;
p2 = &b; //대입해줘야함

printf("%lf\\n",*p2);

char c = 'G';
char* p3=&c;
printf("%c \\n", *p3);

int num = 100;
int* pp = #

*pp = 200; // *pp가 가르키는 주소에 200을 넣어라
printf("%d \\n", num);

printf("input : \\n");
scanf_s("%d", pp); //입력받은 값을 특정 주소에 넣어라
printf("%d \\n", num);

}
#include <stdio.h>

void main()
{
int a = 10;
int b = a; //b에 a의 값을 대입해라

int num = 100;
int* p1 = # //num을 가르킨것임
int* p2;
p2 = p1; //p1이 갖고있는 주소를 대입해라. 주소를 공유함! p2=p1이므로 둘다 같은 주소를 가르킨다.
//에어컨 1개에 리모컨이 2개인 경우
printf("%d \\n", *p1); //넘버 값
printf("%d \\n", *p2);

*p1 = 5000; //p1이 가르키는 곳의 값
printf("%d \\n", *p1); //주소를 공유하고 있으므로 같은 값이 나온다
printf("%d \\n",*p2);

int n1 = 100;
int n2 = 200;
int* ppp; //리모컨으로 에어컨 2개를 제어한다.

ppp = &n1; //n1의 주소를 가르킴
printf("%d \\n", *ppp); //*ppp는 ppp가 가르키는 곳의 값

ppp = &n2;
printf("%d \\n", *ppp); //*ppp는 ppp가 가르키는 곳의 값

}

포인터의 용도

(1) 다른 지역(함수) 지역변수를 제어 할 때

{ }안이 영역이다

값만 보내면 그 데이터를 제어할 방법이 없다.

하지만 주소를 보내면 데이터를 제어 가능

call by Value - 절대로 원본 값은 불변. 안심

call by referance - 바뀔 수 있으니 유의 해야 함.

#include <stdio.h>

void increase(int* p) //메인함수의 a와는 다르다
{
	(*p)++; //우선순위 : ()없으면 *보다 ++이 먼저된다  주소를 ++시키고 거기값. 
	//*p = *p + 1;
}

void main()
{
	int a = 10;//지역변수
	printf("a : %d \\n", a);

	//increase(a); // 증가 작업 기능 호출  인크리즈에 (a)를 던진다
	//printf("a : %d \\n", a);

	increase(&a); // a변수의 주소를 전달해주기
	printf("a : %d \\n", a);
}

(2) 문자열 참조(java string의 전신)  ※문자열을 저장한다라고도함

배열의 이름도 포인터이다.

#include <stdio.h>

void main()
{
	char aaa[10] = "Hello";
	printf(" %s \\n", &aaa[0]); //%s는 주소를 부르는 의미
	printf(" %s \\n", aaa); //같은 의미,깔끔하게 쓸려고! 

	printf(" %s \\n", "android"); //문자열상수, 메모리 어딘가에 android가 있다.
	printf(" %p \\n", "android"); //컴퓨터한테는 주소로보인다

	char* p;
	p = "android";//안드로이드라는 글씨를 넣은것임? 아니다! a가 시작되는 주소로 보인다.
	//문자열상수를 대입하면 문자열의 시작주소가 전달됨. 
	printf(" %s \\n", p);

	int n;
	n = 10;
	printf(" %d \\n", n);

}
#include <stdio.h>

void main()
{
	char aaa[10] = "Hello"; //둘다 문자열 저장하는것임
	char* p = aaa; //배열의 주소를 가르침  //둘다 문자열 저장하는것임
	
	scanf_s("%s", aaa, 10); //최대 글자수 써줘야함!!!
	printf(" %s \\n", aaa);

	scanf_s("%s", p, 10); //aaa라는 배열안에 저장됨 
	printf(" %s \\n", aaa);
}

(3) 지역변수로 만든 배열을 다른 함수에 전달 할 때

배열을 통으로 전달하는게 불가하다. 배열은 값을 전달할수가 없다.

배열의이름aaa는 &aaa[0]의 주소와 같다

배열의 이름은 주소이다.

#include <stdio.h>

void output(int* p) //배열의 [0]번방을 가르키는 자료형을 쓴다
//void output(int p[]) 이렇게 표현해도 된다.(표기법만) 주소니까 8바이트,4바이트가 아니다

{
	printf(" %d \\n", *(p + 0));//* 역 참조 연산자 
    // *p++; //더하기1은 옆방이아니라 옆집을 말한다. 정수형은 4칸 뒤에 옆집을 말함.
    printf(" %d \\n", *(p + 1)); //우선순위조심해야함  *p+1은 11을 말함 조심해야함!! 
	printf(" %d \\n", *(p + 2)); //우선순위조심해야함

  printf(" %d \\n", p[0]); //이것도 가능. 더 간결
	printf(" %d \\n", p[1]);
	printf(" %d \\n", p[2]);
}

void main()
{
	int aaa[3] = {10,20,30}; //4바이트짜리가 3칸만들어짐 100~103 / 104~107/ 108~10b
	output(aaa); //배열이 아니라 첫번째칸의 주소= 즉 주소 를 보내는것임 
	//output(&aaa[0]);  얘는 0번방을 가르키는 주소야!! 0번방만 알아도 주소는 딸려온다

}

(4) 동적 메모리 영역(Heap) 사용 - 4가지 영역 중 하나

RAM

Code
영역
상수, 코드(HDD에서 읽어옴), 함수
: 글씨가 있다. void aaa() . 실행 시 영역이 생김
한번 써지면
바뀌지  않음   

O.S 관장 운영체제에 의해 관리됨

4바이트 등 이미 정해짐

Data
영역
전역변수, static변수
stack
영역
지역변수, 매개변수
(포인터변수, int a, 구조체변수 등 다 여기에 포함)
필요 할 때 만들어지고 함수가 끝나면 사라짐
heap
영역
동적 메모리 영역 - 할당 (생성)해주는 기능(문법X) : malloc(byte 수) ;
말록 : memory allocate - 해제 (소멸)해주는 기능(문법X) : free( ) ;

이 공간 안에 이름표를 붙이는 건 금지 → 이름을 어떻게 부르지? 포인터(=참조변수)로 지시함
예전에는 안 지우면 잔해가 남았음
→ 그 정도로 내가 다 컨트롤
개발자 관장 내 맘대로 할 수 있음
Ex) 정수형 7바이트로 만듬

 

 

 

 

#include <stdio.h>
// #include <malloc.h> 말록과 프리만 쓸수있다.
#include <stdlib.h> //표준 라이브러리. 더 많이 쓴다.

void main()
{
	//Heap메모리에 정수형 숫자를 저장해보기위해
	//4byte의 공간을 받아 보기
	//stdio에 없다 malloc에도 있구 stdlib에도 있다.

	int* p = malloc(4); //할당된 주소를 리턴해줌. 포인터변수로 가르쳐서 제어한다.
	*p = 10;

	printf("%d \\n", *p);

	free(p); //지우기 
}
/* double* p = malloc(8);
*p = 3.14;
printf(" %lf \\n",*p);

char* p2 = malloc(1);
*p2 = 'G';
printf(" %c \\n", p2);/

int aaa[3] = {10,20,30};
int bbb[3] = {100,200,300};
int ccc[3] = {1000,2000,3000};

int* ps[3]; // 포인터 벡터를 3개 묶음. 배열의 요소가 되어 묶인다 
ps[0] = &aaa[0];
ps[1] = bbb[0];
ps[2] = ccc[0];

printf(" %d ", *(ps[0]+0));
printf(" %d ", *(ps[0]+1));
printf(" %d ", *(ps[0]+2));

printf(" %d ", *(ps[1] + 0));
printf(" %d ", *(ps[1] + 1));
printf(" %d ", *(ps[1] + 2));

printf(" %d ", *(ps[2] + 0));
printf(" %d ", *(ps[2] + 1));
printf(" %d ", *(ps[2] + 2));
#include <stdio.h>
// #include <malloc.h> 말록과 프리만 쓸수있다.
#include <stdlib.h> //표준 라이브러리. 더 많이 쓴다.

void main()
{
char* names[3];

names[0] = "sam";    // 배열안에 sam이 있는게 아니라 주소. 포인터 즉 가르키고 있는것이다.
names[1] = "robin";
names[2] = "hong";

for (int i = 0; i < 3; i++)
{
printf(" %s \\n", names[i]);
}

int* p=NULL; //쓰레기값이랑 주소값이랑 일치할수도있어. 그러니까 초기화해야함
//0은 안됨. NULL을 쓴다. 아무것도 안가르킨다.
//초기값은 ? 인트0, 더블 0.0, 캐릭 아스키코드 0, (정수,더블,캐틱 등) 포인터변수는 null
}
728x90
반응형

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

C언어_구조체  (0) 2023.01.24
C언어_배열  (0) 2023.01.24
C언어_함수  (0) 2023.01.23
C언어_제어문  (0) 2023.01.23
C언어_연산자  (0) 2023.01.23