사이먼's 코딩노트

[C언어] 포인터&배열 문제풀이(1) 본문

C언어

[C언어] 포인터&배열 문제풀이(1)

simonpark817 2024. 2. 19. 17:05
  • 이번에는 여지껏 배운 포인터, 배열과 문자열, 공공재 지역에 관한 문제들을 풀어봅시다.

 

[문제 1]

  • 변수 str1, str2, str4의 값이 같은 이유를 설명하세요.
#include <stdio.h>

int main(void) {
    char* str1 = "abc";
    printf("str1 : %ld\n", (long)str1);

    char* str2 = "abc";
    printf("str2 : %ld\n", (long)str2);

    char* str3 = "abcd";
    printf("str3 : %ld\n", (long)str3);

    char* str4 = "abc";
    printf("str4 : %ld\n", (long)str4);

    char str5[10] = "abc";
    printf("str5 : %ld\n", (long)str5);

    return 0;
}
  • main 함수를 실행시켜보면 출력문을 통해 각 배열의 첫 번째 주소값이 출력된다.
  • str1, str2, str3, str4는 문자열 상수가 들어가 있다.
  • str1, str2, str4는 모두 "abc"를 저장하고 있지만, 최초 str1에서 생성된 "abc"가 공공재 지역에 저장되면서 str2나 str4에서 새로 문자열을 생성할 필요가 없기 때문에 서로 바라보는 주소값이 같다.
  • str3은 "abcd"라는 문자열 상수를 새로 생성해야되기 때문에 다른 주소값을 출력한다.
  • str5의 경우 다른 변수들과 다르게 배열의 형태로 생성되었기 때문에 주소값이 다르게 출력된다.

 

[문제 2]

  • 다음은 다중 포인터를 이용하여 change() 함수를 구현해보세요.
#include <stdio.h>

void change(char**** pppp) {
  ****pppp = 'a';
  *(***pppp + 1) = 'b';
  *(***pppp + 2) = 'c';
  *(***pppp + 3) = 'd';
  *(***pppp + 4) = '\0';
}

int main(void) {
    char str[10];

    char* p = str;
    char** pp = &p;
    char*** ppp = &pp;
    change(&ppp);

    printf("%s\n", str);
    // 출력 => abcd

    return 0;
}
  • main 함수를 살펴보면 str이라는 크기가 10인 배열을 생성하였다.
  • 포인터 변수 p는 str의 주소를 가르키고, pp는 p의 주소를 가르킨다.
  • ppp는 pp의 주소를 가르키고 change() 함수의 인자로 ppp의 주소를 넘긴다.
  • 해당 문제는 4중 포인터를 활용하여 각 배열의 위치에 값을 넣어줘야 한다.
  • 우선 change() 함수의 매개변수로는 4중 포인터인 (char**** pppp)를 작성해준다. 여기서 pppp는 ppp의 주소를 가르킨다.
  • "abcd"를 출력하기 위해서는 str[0] 부터 str[4] 까지 차례대로 a, b, c, d, \0 을 넣어줘야한다.
  • ppp의 주소로 이동하고 다시 pp의 주소로 이동하고 p의 주소로 이동하고 char str[]로 이동하기 위해서는 ****pppp 를 작성하면 된다.
  • 이 때 change() 함수에서 배열의 형태를 사용하지 않고 값을 넣는다고 하면 +0 부터 +4까지 증가하면서 해당 문자를 저장한다.
  • *(***pppp + 0) = 'a', *(***pppp + 1) = 'b', *(***pppp + 2) = 'c', *(***pppp + 3) = 'd', *(***pppp + 4) = '\0' 하여 각 배열에 문자를 저장하고 출력문에서 %s를 통해 문장을 출력하면 'abcd' 가 제대로 출력된다.

 

[문제 3]

  • 다음은 문장의 길이를 반환하는 get_str_len() 이라는 함수를 구현해보세요.
#include <stdio.h>

int get_str_len(char* p) {
    int len = 0;

    for(int i = 0; 1; i++) {
        if(p[i] == '\0') {
            break;
        }
        else {
            len++;
        }
    }

    return len;
}

int main(void) {
    char name[100] = "Paul";
    int len = get_str_len(name);

    printf("len : %d\n", len);
    // 출력 => len : 4

    name[0] = 't';
    name[1] = 'o';
    name[2] = 'm';
    name[3] = 'a';
    name[4] = 's';
    name[5] = '\0';

    len = get_str_len(name);

    printf("len : %d\n", len);
    // 출력 => len : 5

    return 0;
}
  • main 함수를 살펴보면 name 이라는 배열은 총 100 바이트의 크기가 지정된 배열이다.
  • 최초에 name이라는 배열에 "Paul"를 저장헀고 해당 문자의 길이를 반환하는 get_str_len() 함수를 실행시키고 길이를 출력하면 4가 나와야한다.
  • 여기서 핵심은 배열의 크기가 크게 지정되어 있어도 결국엔 문자가 저장된 부분만 카운트를 해야하는 것이다.
  • C언어에서 모든 문장은 '\0'로 끝난다는 것을 힌트로 생각해봤을 때 get_str_len() 함수에서 매개변수로 배열의 주소를 받고 반복문을 통해 0번째 부터 검사했을 때 '\0'(널문자) 가 나오면 해당 반복문을 멈추고 해당 배열의 길이를 return 해주면된다.

 

[문제 4]

  • 다음은 문장에서 특정 문자의 위치를 반환하는 함수를 구현해보세요.
#include <stdio.h>

int get_index_of_c(char *p, char pp) {

    int index = -1;

    for(int i = 0; 1; i++) {
        if(p[i] == pp) {
            index = i;
        }
        else if(p[i] == '\0') {
            break;
        }
    }
    return index;
}

int main(void) {
    int index;

    index = get_index_of_c("abc", 'b');
    printf("index : %d\n", index);
    // 출력 => index : 1

    index = get_index_of_c("test", 's');
    printf("index : %d\n", index);
    // 출력 => index : 2

    index = get_index_of_c("test", 'x');
    printf("index : %d\n", index);
    // 출력 => index : -1

    return 0;
}
  • main 함수를 살펴보면 get_index_of_c() 함수를 이용하여 특정 문자의 index 번호를 체크하여 출력하게 되어있다.
  • 예를 들어 get_index_of_c("abc", "b") 이면 "abc"의 문장중에 "b"의 위치는 2번째 있기 때문에 2가 출력된다.
  • 배열의 순서와 index의 순서는 다르다는 점을 유의하여 함수를 구현해야한다.
  • 만약 문장에서 찾고자 하는 특정 문자가 없다면 해당 index는 -1로 출력해야한다.
  • get_index_of_c() 함수에서 매개변수로 전체 문장의 주소인 char* p와 특정 문자의 주소인 char* pp를 받는다.
  • 최초에 index는 -1로 지정하고 return 값이 필요하기 때문에 void가 아닌 int로 함수를 생성한다.
  • 함수의 로직은 다음과 같다. 반복문을 통해 전체 문장인 p를 배열의 0번째 부터 차례대로 특정 문자인 pp와 확인을 하고 만약 두 문자가 같다면 해당 p의 배열의 위치를 index로 저장하고 return 값으로 반환한다.
  • 반복문은 무한루프를 통해 계속 반복되기 때문에 추가로 만약 전체 문장인 p의 배열을 차례대로 확인하다가 문자열의 끝을 나타내는 '\0'이 있다면 break를 통해 반복문을 종료한다.

 

[문제 5]

  • 다음은 전체 문장에서 특정 부분만 잘라서 출력하는 함수를 구현해보세요.
#include <stdio.h>

void print_sub_str(char* p, int start, int count) {
    for(int i = start; i < start + count; i++) {
        if(p[i] == '\0') {
            break;
        }
        printf("%c", p[i]);
    }
    printf("\n");
}

int main(void) {
    print_sub_str("abcd", 2, 2);
    // 출력 => cd

    print_sub_str("abcd", 1, 3);
    // 출력 => bcd

    print_sub_str("abcd", 1, 10);
    // 출력 => bcd

    print_sub_str("abcd", 0, 2);
    // 출력 => ab

    return 0;
}
  • main 함수를 살펴보면 print_sub_str() 함수를 이용하여 특정 부분만 잘라 문자를 출력하게 되어있다.
  • 예를 들어 print_sub_str("abcd", 2, 2) 이면 "abcd"의 문장 중에 2번째 index 지점부터 문자 2개인 "ab" 를 출력한다.
  • print_sub_str() 함수에서 매개변수로 전체 문장의 주소인 char* p와 index의 시작점인 start와 몇 개를 나타내는 count를 받는다.
  • 함수의 로직은 다음과 같다. 반복문을 통해 start부터 start+count까지 반복하면서 각 배열에 위치한 문자를 하나씩 출력해주고 만약 전체 문장인 p의 배열을 차례대로 확인하다가 문자열의 끝을 나타내는 '\0'이 있다면 break를 통해 반복문을 종료한다.
  • 반복문의 범위가 start 부터 start+count 까지인 이유는 특정 부분을 지정해야되기 때문이다.
  • 추가로 반복문을 통해 특정 문자를 추출하여 반복문을 벗어나면 해당 특정문자들을 구별할 수 있는 줄바꿈 출력문을 추가한다.
반응형

'C언어' 카테고리의 다른 글

[C언어] 구조체(Struct)  (0) 2024.02.20
[C언어] 포인터&배열 문제풀이(2)  (0) 2024.02.19
[C언어] 공공재 / strcpy  (0) 2024.02.19
[C언어] define / typedef / 문자 배열  (2) 2024.02.19
[C언어] scanf  (0) 2024.02.14