본문 바로가기
c

6. 포인터

by it_jangyee 2020. 2. 17.

1. 포인터: 주소값을 갖는 변수

1)선언
타입 *변수명;
int *p; //p는 int값의 주소를 갖는 변수
int a = 10;
p = &a;

2) 실행
실행문에서 *는 포인터가 갖고있는 주소에 저장된 값
printf("p=%x, *p=%d\n", p, *p);
*는 값을 읽기 만 가능한 것이라 쓰기도 가능
*p=20; //a도 20이 됨

 

#include <stdio.h>
void main(){
    int *p, a=10;
    p = &a;
    printf("p=%x, &a=%x\n", p, &a);
    printf("*p=%d, a=%d\n", *p, a);

    *p = 20;
    printf("*p=%d, a=%d\n", *p, a);
}
#include <stdio.h>
void main(){
    char a='a', *p_a;//p_a는 char 주소를 갖는 포인터
    int b = 10, *p_b;//p_b는 int 주소를 갖는 포인터
    float c = 3.45f, *p_c;//p_a는 float 주소를 갖는 포인터

    p_a = &a;
    p_b = &b;
    p_c = &c;

    printf("&a=%x, p_a=%x\n", &a, p_a);
    printf("a=%c, *p_a=%c\n", a, *p_a);

    printf("&b=%x, p_b=%x\n", &b, p_b);
    printf("b=%d, *p_b=%d\n", b, *p_b);

    printf("&c=%x, p_c=%x\n", &c, p_c);
    printf("c=%f, *p_c=%f\n", c, *p_c);
}

2. 배열과 포인터

1) 배열의 이름은 배열 첫 요소의 주소

#include <stdio.h>
void main(){
    int a[]={1,2,3,4,5};
    int *p = a;//배열의 이름에는 배열 시작주소값이 있다
    int i;
    for(i=0;i<5;i++){
        printf("%d\t", *(p+i));
    }
    printf("\n");

    p = &a[4];
    for(i=0;i<5;i++){
        printf("%d\t", *(p-i));
    }
}

2) 배열과 포인터는 동치

#include <stdio.h>
void main(){
    int a[] = {1,2,3,4,5};
    int *p = a;
    int i;
    //배열과 포인터는 동치
    for(i=0;i<5;i++){
        printf("%d\t", p[i]);
    }

    printf("\n");

    for(i=0;i<5;i++){
        printf("%d\t", *(a+i));
    }
}
#include <stdio.h>
void main(){
    char a[]="hello";
    char *p = a;
    int i;
    for(i=0;i<5;i++){
        printf("%c", *(p+i));
    }
    printf("\n");

    for(i=0;i<5;i++){
        printf("%c", p[i]);
    }
}

3. 함수호출 규약

1)call by value(값 복사 호출)

#include <stdio.h>
void swap(int a, int b);
void main(){
    int x=10, y=20;
    printf("함수 호출 전=> x:%d, y:%d\n", x, y);
    swap(x, y);
    printf("함수 호출 후=> x:%d, y:%d\n", x, y);
}
void swap(int a, int b){
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

2)call by reference(주소값 복사 호출)

#include <stdio.h>
void swap(int *a, int *b);
void main(){
    int x=10, y=20;
    printf("함수 호출 전=> x:%d, y:%d\n", x, y);
    swap(&x, &y);
    printf("함수 호출 후=> x:%d, y:%d\n", x, y);
}
void swap(int *a, int *b){
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

4. 포인터 왜 타입이 필요한가?

int a;  //일반 변수는 값을 저장하려면 그 타입 크기 만큼 메모리를 할당. 그래서 타입 필요

int *p; //주소의 길이는 모두 같음(int 값의 주소나 char 값의 주소의 길이는 동일)

p=&a; // a의 주소를 포인터 p에 할당

printf("a=%d\n", *p); //포인터 주소가 가르킨 곳에 저장된 값을 읽거나 거기에 값을 쓸때 int타입이면 4B, char라면 1B를 읽고 써야함. 즉 주소로 접근해서 값을 읽고 쓸때 한 단위의 크기를 알려줌

 

5. 2중 포인터: 주소의 주소

#include <stdio.h>
void main(){
    int a = 10;
    int *p = &a;
    int **pp = &p;

    printf("a=%d, p(a의주소)=%x, pp(p의주소)=%x\n", a, p, pp);
    printf("a의 주소=>&a=%x, p=%x, *pp=%x\n", &a, p, *pp);
    printf("a의 값=>a=%d, *p=%d, **pp=%d\n", a, *p, **pp);
}
2중 포인터와 배열
#include <stdio.h>
void main(){
    int a[][3]={{1,2,3},{4,5,6}};
    int (*p)[3] = a;
    int i, j;

    for(i=0;i<2;i++){
        for(j=0;j<3;j++){
            printf("%d\t", *(*(p+i)+j));
        }
        printf("\n");
    }

    for(i=0;i<2;i++){
        for(j=0;j<3;j++){
            printf("%d\t", p[i][j]);
        }
        printf("\n");
    }

}

6. 포인터의 활용

문자열, 배열, 함수는 call by value로 전달 불가. 그러므로 포인터로 전달해야 함.

#include <stdio.h>


//파라메터로 복사해서 전달할 수 없는 것들:문자열, 배열, 함수=>주소 전달
void printArr(int *arr, int size);
void printStr(char *msg);


void main(){
    int a[]={1,2,3,4,5};
    printArr(a, 5);
    printStr("hello pointer");
}
void printArr(int *arr, int size){
    int i;
    for(i=0;i<size;i++){
        printf("%d\t", arr[i]);
    }
    printf("\n");
}
void printStr(char *msg){
    printf("msg:%s\n", msg);
}

문자열 복사, 길이, 비교 함수 만들기
#include <stdio.h>
void my_strcpy(char *s1, char *s2);
int my_strlen(char *s);
int my_strcmp(char *s1, char *s2);
void main(){
    char src[]="hello pointer";
    char dest[20];
    char a[]="abcdefg";

    printf("src:%s\n", src);
    printf("a:%s\n", a);

    my_strcpy(dest, src);
    printf("dest:%s\n", dest);

    printf("src len:%d\n", my_strlen(src));
    printf("dest len:%d\n", my_strlen(dest));
    printf("a len:%d\n", my_strlen(a));

    if(my_strcmp(src, dest)){
        printf("src와 dest는 동일하다\n");
    }else{
        printf("src와 dest는 같지않다\n");
    }

    if(my_strcmp(src, a)){
        printf("src와 a는 동일하다\n");
    }else{
        printf("src와 a는 같지않다\n");
    }
}
void my_strcpy(char *s1, char *s2){
    while((*s1++=*s2++)!='\0');
}
int my_strlen(char *s){
    int cnt=0;
    while(*s++!='\0'){
        cnt++;
    }
    return cnt;
}
int my_strcmp(char *s1, char *s2){
    int len1 = my_strlen(s1);
    int len2 = my_strlen(s2);
    int i;
    if(len1!=len2){
        return 0;
    }
    for(i=0;i<len1;i++){
        if(*s1++!=*s2++){
            break;
        }
    }
    if(i==len1){
        return 1;
    }else{
        return 0;
    }
}

'c' 카테고리의 다른 글

8. 구조체  (0) 2020.02.24
7. 입출력  (0) 2020.02.19
5. 함수  (0) 2020.02.12
4. 배열  (0) 2020.01.22
3. 제어문  (3) 2020.01.08

댓글