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
반응형