[자료구조] 포인터*

K근형·2023년 12월 6일
0

자료구조

목록 보기
1/12

✔️ 포인터의 기본 c

#include <stdio.h>

#pragma warning (disable : 4996)

int main(void)
{
    int a = 5;
    double d = 3.54;

    //주소를 저장하는 변수와 포인터의 타입은 일치
    //포인터는 변수의 상위 주소값만 저장하고 있기 떄문이다.
    //포인터의 타입이 없는 경우 포인터로 역 참조를 할 수 없다.
    int* p1 = &a;
    double *p2 = &d;

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

    // p1이 가리키는 메모리에 접근
    printf("%d\n", *p1); //p1 역참조
    printf("%f\n", *p2); //p2 역참조 
    return 0;
}
출력 값:
5
0x7ff7bfeff238
0x7ff7bfeff238
5
3.540000
**주소값은 달라진다**

✔️ 배열과 포인터 관계 c

#include <stdio.h>

#pragma warning (disable : 4996)

int main(void){
    int a[5] = {10, 20, 30, 40, 50};
    int* p;

    //배열 이름은 배열의 첫 번째 원소의 주소를 가리키는 포인터
    printf("%p\n", a);
    printf("%p\n", &a[0]);

    // p = &a[0];
    p = a;

    return 0;
}

#include <stdio.h>

#pragma warning (disable : 4996)

void fun(int* p)
{
    printf("%d\n", p[0]);
    printf("%d\n", *(p + 0));
}


int main(void)
{
    int a[5] = {10, 20, 30, 40, 50};

    fun(a); // ==fun(&a[0]);
    //주석 설정 : ctrl + k + c
    //주석 해제 : ctrl + k + u
    //int* p;

   ////배열 이름은 배열의 첫 번째 원소의 주소를 가리키는 포인터
   // printf("%p\n", a);
    //printf("%p\n", &a[0]);

    // p = &a[0];
   // p = a;

    return 0;
}
출력 값;
10
10

✔️ 이중 포인터 c

#include <stdio.h>

#pragma warning (disable : 4996)

void fun(int* p)
{
    printf("%d %d %d %d %d\n", p[-2], p[-1], p[0], p[1], p[2]);
    printf("%d %d %d %d %d\n", *(p - 2), *(p - 1), *(p + 0), *(p + 1), *(p + 2));

}
void dummy(double* p)
{
    printf("%.1f %.1f %.1f\n", p[0], p[1], p[2]);
    printf("%.1f %.1f %.1f\n", *(p + 0), *(p + 1), *(p + 2));
}

int main(void)
{
    int a[5] = {10, 20, 30, 40, 50};
    double d[3] = {1.1, 2.2, 3.3};

    fun(a+2); // ==fun(&a[2]);
    dummy(d);
    //주석 설정 : ctrl + k + c
    //주석 해제 : ctrl + k + u
    //int* p;

   ////배열 이름은 배열의 첫 번째 원소의 주소를 가리키는 포인터
   // printf("%p\n", a);
    //printf("%p\n", &a[0]);

    // p = &a[0];
   // p = a;

    return 0;
}
출력 값:
10 20 30 40 50
10 20 30 40 50
1.1 2.2 3.3
1.1 2.2 3.3
#include <stdio.h>

#pragma wanring( disable : 4996)

int main(void)
{
    int a = 5;
    int* p = &a;
    int** p2 = &p;
    int*** p3 = &p2;
 
    /*
     *p ? 5
     p2 ? p주소
     *p2 ? a주소
     **p2 ? 5
     */

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

    return 0;
}
출력 값:
5
5
5
5

✔️ 문자열과 포인터 c

#include <stdio.h>

#pragma warning (disable : 4996)

int main()
{
	int a = 5;
	char c = 'R';

	//문자열 상수 -> 문자열이 저장된 곳의 가장 상위 주소로 처리 
	//'A'는 정수 1바이트 값, "A"는 주소로 2바이트 값을 가진다
	// 문자열의 끝은 항상 '\0'(널문자)으로 끝난다.
	// 문자열은 주소부터 널문자 이전까지를 문자열로 처리한다.
	char* p = "Hello World";
	char* p2 = "odd";

	//%s : 주소부터 널 문자 이전까지 출력해!!!
	printf("%s\n", p);
	printf("%s\n", p2);
	return 0;
}
출력 값:
Hello World
odd
#include <stdio.h>

#pragma warning (disable : 4996)

int main()
{
    int a = 5;
    char c = 'R';

    //문자열 상수 -> 문자열이 저장된 곳의 가장 상위 주소로 처리
    //'A'는 정수 1바이트 값, "A"는 주소로 2바이트 값을 가진다
    // 문자열의 끝은 항상 '\0'(널문자)으로 끝난다.
    // 문자열은 주소부터 널문자 이전까지를 문자열로 처리한다.
    char* p = "Hello World";
    char* p2 = "odd";

    //%s : 주소부터 널 문자 이전까지 출력해!!!
    printf("%s\n", p);
    //printf("%s\n", p + 2) ==> llo 출력
    printf("%s\n", p2);

    printf("%c\n", p[1]); //한 글자만 출력하고 싶을 때
    printf("%c\n", *(p + 1));

    //반복문을 돌면서 한 글자씩 출력
    printf("\n 한 글자씩 문자열 출력\n");

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

    }
    /* 저장된 문자가 널문자와 같지 않다면? 반복 => 문자열의 길이만큼 반복
    for(int i =0; p[i] != '\0'; i++)
    {
        printf("%c", *(p + i)); */
    return 0;
}
출력 값:
Hello World
odd
e
e

 한 글자씩 문자열 출력
H e l l o 

✔️ 포인터 배열 c

#include <stdio.h>

#pragma warning (disable : 4996)

void fun(int** p2)
{
	printf("포인터 배열을 전달 받을 시 이중 포인터로 받는다.\n");
	printf("b의 값을 출력합니다 : %d\n", *p2[0]);
}

int main()
{	
	//널포인터 : 포인터가 가리키는 대상이 없는 경우
	//int* p1 = NULL, * p2 = NULL, * p3 = NULL, * p4 = NULL, * p5 = NULL;
	//포인터 배열 : 포인터 변수가 여러개 필요한 경우 포인터를 배열로 선언할 수 있다. 
	int* p[5] = { NULL }; //포인터 변수 5개 => 8바이트 * 5개 => 40바이트 할당
	int a = 5, b = 10;

	p[2] = &a;
	printf("%d\n", *p[2]);
	p[0] = &b;
	printf("%d\n", *p[0]);

	fun(p); //p == &p[0]
	return 0;
}
출력 값:
5
10
포인터 배열을 전달 받을 시 이중 포인터로 받는다.
b의 값을 출력합니다 : 10

✔️ 문자열과 포인터배열 c

#include <stdio.h>

#pragma warning (disable :4996)

void displayFruit(const char** fruit)
{
    printf("***문자열 단위로 과일명 출력***\n");
    for(int i = 0; i < 5; i++)
    {
        printf("%s\n", fruit[i]);
    }
    printf("***문자열 단위로 과일명 출력***\n");
    for (int i = 0; i < 5; i++)
    {
        //*(fruit[i] + j) == fruit[i][j] == (*(fruint + i))[j] == *((*(fruit + i)) + j)
        for(int j = 0; *(fruit[i] + j) != '\0'; j++)
        {
            printf("%c\n", *(fruit[i] + j)); //한 글자씩 출력
        }
        puts("");; //줄바꿈
    }
}
int main(void)
{
    //포인터가 가리키는 메모리가 상수 영역인 경우 상수 포인터를 선언한다.
    //포인터 s1으로 "apple" 문자열을 수정할 수 없다.
   /* const char* s1 = "apple";
    const char* s2 = "banana";
    const char* s3 = "orange";
    const char* s4 = "strawberry";
    const char* s5 = "pear";*/

    const char* fruit[5] = {
        "apple",
        "banana",
        "orange",
        "strawberry",
        "pear"
    };

    displayFruit(fruit);

    // %s: 주소부터 널문자 이전까지 출력
    for(int i = 0; i < 5; i++)
    {
        printf("%s\n", fruit[i]);
    }
    /*printf("%s\n", fruit[0]);
    printf("%s\n", fruit[1]);
    printf("%s\n", fruit[2]);
    printf("%s\n", fruit[3]);
    printf("%s\n", fruit[4]);*/

    return 0;
}
출력 값 :
***문자열 단위로 과일명 출력***
apple
banana
orange
strawberry
pear
***문자열 단위로 과일명 출력***
a
p
p
l
e

b
a
n
a
n
a

o
r
a
n
g
e

s
t
r
a
w
b
e
r
r
y

p
e
a
r

apple
banana
orange
strawberry
pear

✔️ 짧은 글 연습 프로그램 c

#include <stdio.h>
#include <stdlib.h> //rand, srand
#include <time.h> //time, clock
//#include <conio.h> //_getch //버퍼를 거치지 않고 바로 전송 입출력 함수들(window체제)
#include <string.h> //strlen

#pragma warning (disable :4996)
#define ANSWER_LEN 255

int main(void)
{
    const char* str[10] = {
        "All greatness is unconscious, or it is little and naught",
        "Life is an incurable disease",
        "Variety's the very spice of life",
        "No man is the wiser for his learning",
        "Love is a sickness full of wees, all remedies refusing",
        "Be great in act, as you have been in thought",
        "A rose is sweeter in the bud than full blown",
        "Genius must be born, and never can be taught",
        "Custom reconciles us to everything",
        "The happiest women, like the happiest nations, have no history"
    };
    int no;
    char answer[ANSWER_LEN];
    char isExit;
    int correct;
    //typedef long clock_t;
    clock_t begin, end;

    srand((unsigned int)time(NULL)); //seed초기화
    do
    {
        no = rand() % 10; //0~9까지의 랜덤수 수출
        printf("%s\n", str[no]);

        begin = clock();
        fgets(answer, ANSWER_LEN, stdin);
        end = clock();

        correct = 0;
        //정확도 계산 => 맞은개수 / strlen(str[no]) *100
        for(int i = 0; answer[i] != '\0'; i++)//입력 받은 길이만큼 반복
        {
            if(answer[i] == str[no][i]) //입력값 == 문제를 한 글자씩 비교
            {
                ++correct ;
            }
        }
        printf("%d", correct);
        printf("\n\n\t\t정확도 : %.2f", (double)correct / strlen(str[no])/100);
        // #define CLOCK_PER_SEC ((clock_t)1000)
        printf("입력 시간 : %.3f\n", ((double)end - begin)/ CLOCKS_PER_SEC);


        printf("\n\t\t계속(아무키) / 종료(Q/q)");
        //isExit = _getch(); //한 글자 입력 함수(버퍼를 거치지 않기 떄문에 엔터를 입력할 필요가 없다.
        getchar();
        isExit = getchar();

       // system("clear"); //윈도우에서는 system("cls"); // clear screen
    } while(isExit != 'Q' && isExit != 'q'); //Q/q와 같지 않다면 반복!!!

    return 0;
}

✔️ void 포인터

#include <stdio.h>

#pragma warning (disable : 4996)

int main(void)
{
    int a = 5;
    int* p = &a;

    double d = 3.5;
    double* pD = &d;

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


    void* pV; //타입 없는 포인터 : 어떤 타입의 주소든 저장할 수 있다. //역참조 불가능
    pV = &a;
    printf("%d\n", *(int*)pV);

    pV = &d;
    printf("%f\n", *(double*)pV);

    return 0;
}
출력 값 :
5
3.500000
5
3.500000
profile
진심입니다.

0개의 댓글