IT공부/IT서적

[윤성우 열혈 C프로그래밍] Part2. 포인터 배열의 시작

shine94 2024. 7. 19. 22:47

** 배열의 이름을 대상으로 하는 sizeof 연산의 결과로는 바이트 단위의 배열 크기가 반환된다.

 

** 널(NULL) 문자의 아스키 코드 값은 0이다.

   그리고 이를 문자의 형태로 출력할 경우, 아무런 출력이 발생하지  않는다.

 

** C 언어에서 표현하는 모든 문자열의 끝에는 널 문자가 자동으로 삽입된다.

 

** 메모리 상에서 문자열을 이진 데이터로 저장하기 때문에

   문자열의 시작과 끝이 표시되어 있지 않다면, 문자열을 구분하는 것은 불가능

 

** 포인터 변수란 메모리의 주소 값을 저장하기 위한 변수

   ㄴ 포인터변수 = 변수 형태의 포인터 + 상수 형태의 포인터

 

** 포인터형(type)

 : 포인터  변수의 선언 및 구분에 사용

 

** &

 : 피연산자의 주소값을 반환하는 연산자

 

** *

: 포인터가 가리키는 메모리는 참조하는 연산자

 

** 포인터의 형이 존재하는 이유는 포인터 기반의 메모리 접근기준을 마련하기 위함이다.

    포인터에 형이 존재하지 않는다면 * 연산을 통한 메모리 접근이 불가능한다.

 

** 잘못된 포인터 사용과 해결책

   예1) 초기화 안함 → 쓰레기 값으로 초기화

   예2) 임의의 값을 넣음 → 임의의 값이 어디인지 알고 초기화를 하는가?

                                            결국, 쓰레기값 초기화와 다를 바가 없음

 

   => 포인터 변수를 우선 선언만 해놓고 이후에 유효한 주소 값을 채워 넣을 생각이라면,

        널(NULL) 포인터로 초기화

           ㄴ 아무데도 가리키지 않는다!

                ㄴ 따라서, 이를 이용한 * 연산은 메모리 공간에 어떠한 영향도 미치지 않음

 

   비록 에러는 나지만,

   잘못된 메모리 접근에 대해 보호장치가 없는 운영체제에서도 시스템에 치명적인 영향을 끼지지 않음

 

** 배열의 이름은 상수 형태의 포인터

  포인터 변수 배열의 이름(포인터 상수)
이름이 존재? 존재 존재
무엇을 저장? 메모리 주소 값 메모리 주소 값
주소의 값 변경 가능? 가능 불가능

 

** arr[i] == *(arr + 1)

 

** 배열을 기반으로 하는 변수 형태의 문자열 : 변경 가능,

   포인터 기반으로 하는 상수 형태의 문자열 : 변경 불가능

 

=> 배열이름 str1은 계속해서 str1[0]에 저장된 문자 M이 가리키는 상태이어야 함

     하지만, 포인터 변수 str2는 다른 위치를 가리킬 수 있음

 

   https://dojang.io/mod/page/view.php?id=328

  https://dphater.tistory.com/entry/18C%EC%96%B8%EC%96%B4-%EB%AC%B8%EC%9E%90%EC%97%B4

 

18.(C언어) 문자열

문자열은 말 그대로 문자의 나열이다. 지금까지 char형 변수에 문자를 하나씩 저장하여 사용하였다. char ch='a'; 문자 a를 ch에 할당 문자열은 이러한 문자들의 나열이다. 처음 C를 시작할때 printf함

dphater.tistory.com

  https://m.blog.naver.com/dlscjs8646/222166081854

 

C의 char* 그리고 C++의 const char*

학교 과제를 할 때, 참고코드를 받아서 작업을 하곤 하는데, 이따금씩 원본이 char*로 되어있어서 const ch...

blog.naver.com

 

** 포인터 배열 : 포인터 변수로 이뤄진, 그래서 주소 값의 저장이 가능한 배열

 

** 문자열 배열 : 문자열의 주소 값을 저장할 수 있는 배열

   ㄴ char형 포인터 배열은 문자열의 주소 값을 저장할 수 있는 배열이다 보니 문자열 배열이라고 부름

 

** 큰따옴표로 묶어서 표현되는 문자열은 그 형태와 상관없이 메모리 공간에 저장되고,

    그 위치에 저장된 문자열의 주소값이 반환

 

** 인자전달의 기본 방식은 값의 복사

    ㄴ 즉, 함수 호출시 전달되는 인자의 값은 매개변수에 복사 

 

** 값을 전달하는 형태의 함수 호출 : Call-by-value

 

** 주소 값을 전달하는 형태의 함수 호출 : Call-by-reference

 

** const는 변수를 상수화하는 목적도 있지만, 포인터 변수를 대상으로도 선언 가능

   ㄴ 포인터 변수가 참조하는 대상의 변경을 허용하지 않는 const 선언을 할 수 있음

 

** 도전 프로그래밍2

1.

#include <stdio.h>

void PrintOddNum(const int* ptr, const int size)
{
    printf("Odd : ");
    for (int i = 0; i < size; i++)
    {
        if (*(ptr + i) % 2 == 1)
            printf("%d  ", *(ptr + i));
    }
    printf("\n");
}

void PrintEvenNum(const int* ptr, const int size)
{
    printf("Even : ");
    for (int i = 0; i < size; i++)
    {
        if (*(ptr + i) % 2 == 0)
            printf("%d  ", *(ptr + i));
    }
    printf("\n");
}

int main(void)
{
    int num[10];
    printf("Enter a total of 10 numbers\n");
    for (int i = 0; i < sizeof(num) / sizeof(int); i++)
    {
        printf("input : ");
        scanf("%d", &num[i]);
    }

    printf("\n");
    PrintOddNum(num,  sizeof(num) / sizeof(int));
    PrintEvenNum(num,  sizeof(num) / sizeof(int));

    return 0;
}

 

 

2.

#include <stdio.h>

int main(void)
{
    int num;
    int size = 0;
    int result[100];

    printf("Enter Decimal integers : ");
    scanf("%d", &num);

    while (num > 0)
    {
        const int remainder = num % 2;
        num /= 2;
        result[size] = remainder;
        size += 1;

    }

    printf("\n");

    for (int i = size - 1; i >= 0; i--)
    {
        printf("%d", result[i]);
    }

    return 0;
}

 

 

3.

#include <stdio.h>

int main(void)
{
    int num[10];
    int result[10];
    int front = 0;
    int back = 9;

    printf("Enter 10 numbers\n");
    for (int i = 0; i < 10; i++)
    {
        printf("intput : ");
        scanf("%d", &num[i]);
    }


    for (int i = 0; i < sizeof(num) / sizeof(int); i++)
    {
        if (num[i] % 2 == 0)
        {
            result[back] = num[i];
            back -= 1;
        }
        else
        {
            result[front] = num[i];
            front += 1;
        }
    }

    printf("\n");
    printf("Output of elements in an array : ");
    for (int i = 0; i < sizeof(num) / sizeof(int); i++)
    {
        printf("%d ", result[i]);
    }

    return 0;
}

 

 

4.

#include <stdio.h>

void CheckPalindrome(const char inputString[])
{
    int size = 0;
    while (inputString[size] != 0)
    {
        size += 1;
    }

    int front = 0;
    for (int back = size - 1; back >= 0; back--) 
    {
        if (inputString[front] != inputString[back])
        {
            printf("Not Palindrome");
            return;
        }
        front += 1;
    }
    printf("Palindrome");
}

int main(void)
{
    char inputString[100];
    printf("Input String : ");
    scanf("%s", inputString);

    CheckPalindrome(inputString);

    return 0;
}

 

▼ string.h에 선언되어 있는 strlen 이란 함수 이용

#include <stdio.h>
#include <string.h>

void CheckPalindrome(const char inputString[])
{
    const int size = strlen(inputString);

    int front = 0;
    for (int back = size - 1; back >= 0; back--) 
    {
        if (inputString[front] != inputString[back])
        {
            printf("Not Palindrome");
            return;
        }
        front += 1;
    }
    printf("Palindrome");
}

int main(void)
{
    char inputString[100];
    printf("Input String : ");
    scanf("%s", inputString);

    CheckPalindrome(inputString);

    return 0;
}

 

 

5.

#include <stdio.h>

int main(void)
{
    int data[] = {3, 2, 4, 1};

    const int size = sizeof(data) / sizeof(int);

    int first = 0;
    int second = 1;
    int endIdx = size - 1;
    while (1) {
        printf("%d %d / ", first, second);
        if (data[first] > data[second])
        {
            const int temp = data[first];
            data[first] = data[second];
            data[second] = temp;
        }

        if (endIdx < 2)
            break;

        if (second < endIdx)
        {
            first += 1;
            second += 1;
        }
        else
        {
            first = 0;
            second = 1;
            endIdx -= 1;
            printf("\n");
        }
    }
    printf("\n\n");

    for (int i = 0; i < size; i++)
    {
        printf("%d ", data[i]);
    }

    return 0;
}

 

▼ 책 버블 정렬

#include <stdio.h>

void BubbleSort(int ary[], int len) {
    for (int i = 0; i < len - 1; i++) {
        for (int j = 0; j < len - i - 1; j++) {
            if (ary[j] > ary[j + 1]) {
                const int temp = ary[j];
                ary[j] = ary[j + 1];
                ary[j + 1] = temp;
            }
        }
    }
}

int main(void)
{
    int data[] = {3, 2, 4, 1};

    const int size = sizeof(data) / sizeof(int);

    BubbleSort(data, size);

    for (int i = 0; i < size; i++)
        printf("%d ", data[i]);

    return 0;
}

 

 

** 해당 글은 윤성우의 열혈 C프로그래밍 도서를 읽고 정리한 글입니다.

  https://product.kyobobook.co.kr/detail/S000001589148

 

윤성우의 열혈 C 프로그래밍 | 윤성우 - 교보문고

윤성우의 열혈 C 프로그래밍 | 윤성우 열형강의『C 프로그래밍』은 C언어에 대한 기본을 배울 수 있는 개론서이다. 이 책은 총 4개의 파트로 구성이 되어 있다. C언어의 기본이 되는 내용들을 다

product.kyobobook.co.kr