포인터, 메모리주소
- 메모리란 ? 저장공간
- 주소란 ? 메모리안에서 저장공간의 위치
- 변수란? 메모리안에서 할당된 저장공간. 값을 저장.1, 'a'
- 포인터란 ? 주소를 저장하는 변수
&: 어드레스 연산자(주소 연산자)
변수앞에 붙이면 변수의 주소를 알아낼 수 있다.
* : 참조연산자
변수에 담긴 주소에 있는 데이터(포인터가 가리키는 데이터)
#include int main()
{
//변수 선언 (값을 저장하는 변수)
int num1 = 10;
int num2 = 20;
//포인터 선언 (주소를 저장하는 변수)
int * p_num = NULL; //0과 같은 포인터 변수의 디폴트 값
p_num = &num1;
//&num1: num1의주소를 p_num에 대입.
//출력(변수에 들어있는 값을 읽기)
printf("num1 = %d\n", num1);
printf("num2 = %d\n", num2);
printf("&num1 = %p\n", &num1);
printf("p_num = %p\n", p_num); //0073FBB0
//%p: 포인터를 위한 출력지정자. (16진수)
//1byte =8bit =4bit(16) + 4bit
//주소 = 4byte. =32bit운영체제용
printf("*p_num = %d\n", *p_num);
printf("sizeof num1 = %d\n", sizeof(num1));
printf("sizeof p_num = %d\n", sizeof(p_num));
}
//목표: 포인터사용예.
//함수로 2개 이상의 값을 변경하고자 할 때
//한개만 변경하고자 할 때는 return으로 받으면 됨.
//swap(a,b) function을 만들기 : a에 b의 값을, b에 a의 값을 대입
#include <stdio.h>
void swap(int *a, int* b)
{
int temp=0;
temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=10;
int b=20;
printf("a= %d b= %d \n", a,b ) ;
swap(&a,&b);
printf("a= %d b= %d \n", a,b ) ;
}
// 목표 : 포인터사용예 #2
// 함수에서 배열을 넘기고자 할 때
// 배열을 다른 함수로 넘긴다고 가정해보자. arr[1,000,000]
// 만약에 데이터를 넘길때마다 복사를 한다면 속도, 메모리의 엄청남 성능 저하.
// 해결책 : 복사를 하지 말고 배열의 이름(=주소)만 넘기면 됨.
// 호출된 함수는 배열의 이름을 포인터로 받으면 해결.
// 호출된 함수는 배열이 넘어갈 때 배열의 사이즈를 알 수 있는 방법이 없으므로
// 반드시! 배열의 크기도 넘겨줘야 한다. parameter로 받는다는 의미.
#include <stdio.h>
#define SIZE 5
void print1(int * p_arr, int count){ // 스트링출력= 문자(아스키코드= 숫자 48 ~ 122)
int i = 0;
//출력#1
for( i = 0; i < count; i++){
printf("%c", p_arr[i]);
}
printf("\n");
}
void print2(int * arr, int count){
int i = 0;
//출력#2
for( i = 0; i < count; i++){
printf("%d\n", *(arr+i));
}
printf("\n");
}
void change_arr(int * arr, int count){
int i =0;
for( i = 0; i < count; i++){
arr[i] += 100;
printf("%d\n", *(arr+i));
}
}
// 참조연산자 arr[i] = *(arr+i)
void change_arr2(int * arr, int count){
int i =0;
for( i = 0; i < count; i++){
*(arr+i) += 100;
}
}
int main(){
int arr[SIZE] = {65, 66, 67, 68, 69}; //SIZE를 지정안하면 초기값개수만큼 배열의 크기가 정해짐.
int arr2[3] = {70, 71, 72};
int i = 0;
print1(arr, SIZE);
print1(arr2, 3);
print2(arr, SIZE);
//quiz : arr배열 각 원소에 100씩 더한 후, arr을 출력하세요. (print1()이나 print2()를 이용)
change_arr(arr, SIZE);
}
배열이름의 의미와 인덱스 의미
[] 인덱스 연산자
배열을 참조연산자 *로 접근하는 방법
arr[i] = *(att+i) 중요!!
#include
#define SIZE 5
int main()
{
int arr[SIZE] = {65,66,67,};
int i=0;
for(i=0; i printf("%d\n", arr[i]);{
printf("%d\n", arr[i]);
}
printf("주소를 이용하여 출력\n");
for(i=0; i <SIZE; i++){
printf("%p %d\n", arr+i, *(arr+i));
//1 =1byte가 아니고 1*sizeof(int).
//int배열이므로. 배열의 원소가 int type이므로
}
//배열의 크기
printf("size of arr: %d\n", sizeof(arr[0]));
printf("size of arr: %d\n", sizeof(arr));
printf("arr = %p \n", arr);
//배열의 이름은 배열이 시작되는 메모리의 주소이다.
//%p :주소, 포인터를 나타내는 출력지정자.헥사값(16진수값)
}
// 목표 : 배열의 이름과 배열 인덱스의 의미
// int type으로 intArr[]를 선언하고 사용자로부터 5개의 정수를 입력받고 출력하되,
// 배열인덱스를 사용하지 말고 참조연산자 *만을 사용하라.
// 1.배열인덱스 사용해서 arr[i] arr은 주소, 주소는 포인터(주소를 담는 변수)에 담김.
// 2.참조연산자 사용해서 *(att+i)
//arr[i] = *(arr+i)
#include <stdio.h>
#define SIZE 5
void array_inout(){
int arr[SIZE] = { 0, }; // 부족한 값은 0으로 채워서 초기화가 됨.
int i = 0;
printf("정수 %d개 입력하세요\n", SIZE);
for( i=0; i<SIZE; i++) {
scanf_s("%d", &arr[i]); //&arr[i] : 주소 &arr[i] = &num
}
printf("입력된 값은 : \n");
for( i=0; i<SIZE; i++) {
printf("%d ", arr[i]); //&arr[i] : 주소 &arr[i] = &num
}
printf("\n");
}
//void pointer_inout(){
//
// int arr[SIZE] = { 0, }; // 부족한 값은 0으로 채워서 초기화가 됨.
// int i = 0;
// printf("정수 %d개 입력하세요\n", SIZE);
//
// for( i=0; i<SIZE; i++) {
// scanf_s("%d", arr+i); //arr: 주소 arr+i = &arr[i]: 주소
// }
//
// printf("입력된 값은 : ");
// for( i=0; i<SIZE; i++) {
// printf("%d ", *(arr+i)); //*arr : 값 arr[i] = *(arr+i) : 값
// }
// printf("\n");
//}
int main(){
array_inout();
//pointer_inout();
포인터와 배열이름
- 배열이름(상수)과 포인터(변수)는 완벽하게 똑같이 동작한다.
- 포인터(변수) = 배열이름(상수) **가장 중요함!!**
- a=1 printf("%d",a) printf("%d",1) 와 같은 원리 a = 변수, 1은 상수.
- a=1, b=2일 때 a=b:a라는 변수에 b에 담긴 값(2)가 대입
- lvalue : = 중심으로 왼쪽에 있는 값 (변수)
- rvalue : = 중심으로 오른쪽에 있는 값 (값) 배열이름 = 포인터
#include
#define SIZE 5
int main(){
int arr[SIZE] = { 65, 66, 67, 68, 69}; //선언과 초기화 동시에.
int i = 0;
//포인터 선언
int * p_arr= arr; //선언과 초기화 동시에
printf("%p %p\n", arr, p_arr);
//출력#1
for( i = 0; i < SIZE; i++ ){
printf("%d ", arr[i]); // arr은 상수이기때문에 arr++표현 쓸 수 없음, 3++
}
printf("\n");
//출력#2 arr[i] = *(arr+i)
for( i = 0; i < SIZE; i++ ){
printf("%d ", *(arr+i));
}
printf("\n%p\n", p_arr);
//출력#3 포인터
for( i = 0; i < SIZE; i++ ){
printf("%d %p\n", *(p_arr+i), p_arr);
}
printf("\n%p\n", p_arr);
//출력#4 포인터가 변수라는 점을 활용해서 ++표현
for( i = 0; i < SIZE; i++ ){
printf("%d %p\n", *(p_arr++),p_arr); //i++
}
printf("\n%p\n", p_arr);
//출력#5 포인터는 배열이름과 완벽하게 동일하게 작동한다는 점을 활용해서
p_arr = arr;
for( i = 0; i < SIZE; i++ ){
printf("%d %p\n", p_arr[i], p_arr);
}
printf("\n%p\n", p_arr);
}
'C언어 > 복습' 카테고리의 다른 글
[C언어]DAY11_1차배열 포인터의 사용예 (내림차순 정리) (0) | 2020.02.01 |
---|---|
[C언어]DAY10_2차원 배열 (0) | 2020.02.01 |
[C언어]DAY7_지역변수, 전역변수, 배열 (0) | 2020.01.30 |
[C언어]DAY6_while(반복문), do whlie, 함수 (0) | 2020.01.28 |
[C언어]DAY5_다중(multiple) if, switch문, 단일 for문, 중복 for문 (0) | 2020.01.21 |