Tech Trail

[정보처리기사 실기] C언어 프로그래밍 특강(4) 본문

Learning/정보처리기사

[정보처리기사 실기] C언어 프로그래밍 특강(4)

_밍지_ 2023. 11. 16. 11:05
728x90
반응형
SMALL

25번 문제

#include <stdio.h>

int x = 0; //전역 변수

foo();

main() {
    foo();
    foo();
}

foo() {
    static int a = 0; // 내부 정적 변수! 초기화 한 번만!
    a += 10;
    x = x + 2;
    printf("%d %d", a, x);
}

이 코드는 함수 foo()main() 함수를 정의하고, 전역 변수 x를 사용하여 값을 출력하는 내용을 포함하고 있습니다. 또한, foo() 함수 내부에는 정적(static) 변수 a가 사용되어 있습니다.

1. 프로그램이 시작됩니다. 전역 변수 x는 0으로 초기화됩니다.

2. main() 함수가 호출됩니다.

3. 첫 번째 foo() 함수 호출

  • foo() 함수 내부에서 정적 변수 a는 0으로 초기화됩니다.
  • a에 10을 더하여 a는 10이 되고, x에 2를 더하여 x는 2가 됩니다. (x가 선언되어 있지 않아서 전역변수사용)
  • printf("%d %d", a, x);가 실행되어 "10 2"가 출력됩니다.

4. 두 번째 foo() 함수 호출:

  • foo() 함수 내에서 정적 변수 a는 10에서 시작하며, 10을 더해 20이 되고, x는 2를 더해 4가 됩니다.
  • printf("%d %d", a, x);가 실행되어 "20 4"가 출력됩니다.
10 220 4
 

 

26번 문제

#include <stdio.h>

int a[] = {1, 0, 3, 0, 5};

void main() {
    int *p = a;
    while (*p)
        printf("%3d", *p++);
}

주어진 코드는 배열 a를 순회하면서 0이 아닌 요소를 출력하는 프로그램입니다.

1. a라는 정수형 배열이 선언되고 초기화됩니다. 배열 요소는 {1, 0, 3, 0, 5}입니다.

2. 포인터 p가 배열 a의 첫 번째 요소를 가리키도록 초기화됩니다.

이제 while 루프가 시작됩니다.

1. while(*p) 조건을 확인합니다. 포인터 p가 현재 가리키는 요소를 역참조하여 해당 요소의 값이 0인지 검사합니다.

2. 현재 p가 가리키는 요소는 1이므로 조건은 참입니다. (0은 거짓, 0 외의 다른 숫자는 참이기 때문)

3. *p를 출력하고, 출력 형식은 "%3d"를 사용하여 1을 출력합니다. 출력은 " 1" 형태로 나타납니다.

4. p++로 인해 p를 다음 요소로 이동시킵니다. 현재 p는 배열의 두 번째 요소를 가리키게 됩니다.

5. while(*p) 조건을 다시 확인합니다. 이번에는 p가 가리키는 요소가 0이므로 조건은 거짓이 됩니다.

6. 루프가 종료됩니다.

따라서 코드는 배열 a를 순회하면서 0이 아닌 요소를 출력하고, 결과적으로 " 1"을 출력합니다.

1

 

 

 

27번 문제

#include <stdio.h>

void swap(int *A, int *B) {
    int *temp;    // 포인터 temp를 선언합니다.
    temp = A;     // 포인터 temp에 A의 주소를 할당합니다.
    *A = *B;      // A가 가리키는 메모리에 B가 가리키는 값을 복사합니다.
    B = temp - 10; // B에 temp에서 10을 뺀 주소를 할당합니다. (진짜 말도 안 되는 코드;;)
}

void main() {
    int a = 10;  // 정수 변수 a를 선언하고 10으로 초기화합니다.
    int b = 20;  // 정수 변수 b를 선언하고 20으로 초기화합니다.
    swap(&a, &b); // swap 함수를 호출하여 a와 b의 값을 교환하려고 합니다.
    printf("%d %d", a, b); // a와 b의 값을 출력합니다.
}
  1. swap 함수가 호출되면 AB에는 각각 ab의 주소가 전달됩니다. 예를 들어, a의 주소가 100이고 b의 주소가 200이라고 가정합니다.
  2. temp 포인터 변수가 선언되고, temp = A; 라인에서 tempA의 주소가 할당됩니다. 따라서 temp는 100의 값을 가집니다. 이제 tempa와 같은 주소를 가리키고 있습니다.
  3. *A = *B; 라인에서 *Aa의 값을 나타내고, *Bb의 값을 나타냅니다. 따라서 이 라인은 ab의 값을 복사하는 역할을 합니다. 따라서 a의 값은 b의 값인 20으로 변경됩니다.
  4. 이제 B = temp - 10; 라인을 살펴보겠습니다. temp는 현재 a의 주소인 100을 가리키고 있으며, 여기서 10을 뺀 주소를 B에 할당하려고 합니다. 그러나 이것은 잘못된 연산입니다. 왜냐하면 B에 90을 할당하는 것은 b의 주소를 변경하는 것이 아니라 B를 가리키는 포인터가 90을 가리키도록 하는 것입니다. 즉, b의 값을 변경하지 않습니다.
20 20
 

참고: 역참조(*)는 포인터 변수를 사용하여 해당 주소에 저장된 값을 읽거나 수정하는 데 사용되는 연산자입니다. 포인터 변수는 다른 변수의 주소를 저장하고, 역참조를 사용하면 해당 주소의 데이터에 접근할 수 있습니다.

 

28번 문제

#include <stdio.h>

int main() {
    static char *c[] = {"aaa", "bbb", "ccc"};
    printf("%s", *(c + 1));
    printf("%s", *c + 2);
}
  1. static char *c[]은 문자열 포인터 배열 c를 선언합니다. 이 배열에는 문자열 포인터들이 저장됩니다.
  2. c 배열에 초기화된 문자열 포인터들이 있습니다. "aaa", "bbb", "ccc"는 각각 c[0], c[1], c[2]에 저장됩니다.
  3. printf("%s", *(c + 1));c 배열에서 두 번째 요소인 c[1]을 출력합니다. 따라서 "bbb"가 출력됩니다.
  4. printf("%s", *c + 2);c 배열의 첫 번째 요소인 c[0]의 주소에 2를 더한 위치부터 문자열을 출력합니다. 즉, "aaa"의 주소에서 2를 더한 위치부터 출력합니다. 따라서 "a"가 출력됩니다.

참고: *c = *(c + 0) = c[0]

따라서 출력 결과는 "bbba"가 됩니다.

bbba

여기서 주의할 점은 *cc[0]을 가리키는 포인터이며, *c + 2"aaa"의 주소에서 2를 더한 위치를 가리킵니다.

 

29번 문제

#include <stdio.h>

int main() {
    int data[][3] = {1, 3, 4, 5, 2, 9, 6, 8, 7};
    int *p = data[1];
    int x, y;
    x = *p;
    y = *(p + 2);
    printf("x = %d, y = %d \n", x, y);
}
  1. int data[][3]는 2차원 정수 배열 data를 선언합니다. 이 배열에는 3개의 열을 가진 3개의 행이 있습니다. 각 행에는 3개의 정수가 저장됩니다.
  2. data 배열에 초기화된 값이 있습니다. 이 배열은 다음과 같은 구조를 가집니다.
1 3 4 // data[0]
5 2 9 // data[1]
6 8 7 // data[2]
 

3. int *p = data[1];는 포인터 p를 선언하고 data[1] 즉, 배열 data의 두 번째 행을 가리키도록 합니다. 이로써 p{5, 2, 9} 배열의 첫 번째 요소를 가리키게 됩니다.

4. x = *p;p가 가리키는 주소에 있는 값을 변수 x에 할당합니다. p{5, 2, 9} 배열의 첫 번째 요소를 가리키므로, x는 5가 됩니다.

5. y = *(p + 2);p가 가리키는 주소에서 2를 더한 위치에 있는 값을 변수 y에 할당합니다. p{5, 2, 9} 배열의 첫 번째 요소를 가리키므로, y는 9가 됩니다.

6. 마지막으로 printf 함수를 사용하여 xy의 값을 출력합니다. 출력 결과는 "x = 5, y = 9"가 됩니다.

x = 5, y = 9

 

30번 문제

#include <stdio.h>

void main() {
    int a[] = {2, 4, 6, 8, 10}; // 정수 배열 a를 선언하고 초기화합니다.
    int b, c;
    int *p = a + 3; // 포인터 p를 배열 a의 네 번째 요소를 가리키도록 초기화합니다.

    b = *p - 2; // p가 가리키는 값에서 2를 뺀 값을 b에 할당합니다.
    c = p[-2]; // p에서 두 번째 이전 요소의 값을 c에 할당합니다.

    printf("%d, %d\n", b, c); // b와 c의 값을 출력합니다.
}

1. int a[] = {2, 4, 6, 8, 10};은 정수 배열 a를 선언하고 초기화합니다. 이 배열에는 2, 4, 6, 8, 10이 순서대로 저장되어 있습니다.

2. int *p = a + 3;은 포인터 p를 배열 a의 네 번째 요소를 가리키도록 초기화합니다. 즉, p는 8을 가리키게 됩니다.

  • a는 배열 a의 시작 주소를 나타냅니다. 배열의 이름은 해당 배열의 첫 번째 요소의 주소를 가리키므로 a는 배열 a의 첫 번째 요소인 2를 가리킵니다.
  • a + 3은 배열 a의 시작 주소 a에서 세 칸 뒤로 이동한 주소를 계산합니다. 즉, 네 번째 요소를 가리킵니다. 따라서 p는 배열 a의 네 번째 요소인 8을 가리키게 됩니다.

3. b = *p - 2;p가 가리키는 값인 8에서 2를 뺀 값을 b에 할당합니다. 따라서 b는 6이 됩니다.

4. c = p[-2];에서 p[-2]p에서 두 칸 뒤로 이동한 위치에 있는 값을 나타냅니다. 즉, p에서 시작하여 두 번째 이전 요소를 의미합니다. p는 8을 가리키고 있기 때문에 c는 4가 됩니다.

5. printf("%d, %d\n", b, c);는 변수 bc의 값을 출력합니다. 출력 결과는 "6, 4"이 됩니다.

6, 4

 

31번 문제

#include <stdio.h>
#include <string.h> // strlen 함수를 사용하기 위해 헤더를 포함합니다.

int main(int argc, char* argv[]) { // 문제 푸는 데 지장 없어. 쫄지마.
    int n, i;
    char p[] = "korea seoul"; // 문자열 p를 선언하고 초기화합니다.
    n = strlen(p); // 문자열 p의 길이를 계산하여 n에 저장합니다.

    for (i = n - 1; i >= 0; i--) {
        printf("%c", p[i]); // 문자열 p를 역순으로 출력합니다.
    }

    printf("%d", n); // 문자열 p의 길이를 출력합니다.
    return 0;
}
  1. int n, i;는 정수형 변수 ni를 선언합니다.
  2. char p[] = "korea seoul";은 문자열 p를 선언하고 초기화합니다. 이 문자열에는 "korea seoul"이 저장됩니다.
  3. n = strlen(p);는 문자열 p의 길이를 계산하여 n에 저장합니다. 따라서 n에는 11이 저장됩니다.
  4. for (i = n - 1; i >= 0; i--)은 반복문을 사용하여 문자열 p를 역순으로 출력하는 부분입니다. i를 초기값으로 n - 1로 설정하고, i가 0보다 크거나 같을 때까지 반복하며 i를 감소시킵니다.
  5. printf("%c", p[i]);는 문자열 p의 각 문자를 역순으로 출력합니다.
  6. 마지막으로 printf("%d", n);은 문자열 p의 길이인 n을 출력합니다. 따라서 출력 결과는 "luoes aerok11"이 됩니다.
luoes aerok11

 

 

 

 

 

💡 이 게시글은 PC 환경에 최적화하여 작성되었습니다.

💡 위 내용은 에듀윌에서 무료로 제공한 '정보처리기사 비밀 언어 특강' 문제를 직접 풀고 정리한 것입니다.

틀린 부분이 있다면 언제든 댓글 남겨주세요 :)

💡정보처리기사 실기 시험을 준비하시는 분들께는 아래 링크에서 해당 강의를 먼저 듣는 것을 권장합니다.

IT 자격증 1위 에듀윌 (eduwill.net)

728x90
반응형
LIST