본문 바로가기
Programming/C

[C언어] 마름모 별 찍기, 정수 거꾸로 변환, 소수 판별, 포인터 개념

by 고간디 2024. 3. 15.

[동아리] A반 3차 2일 과제 (2024.03.15)

여러 기능을 수행하는 코드를 작성해주세요.
1 -> 정수를 입력 받고 그 크기의 마름모 모양 찍기
2 -> 세 자리 이상의 정수를 입력 받고 거꾸로 출력하기
3 -> 입력 받은 정수가 소수인지 확인
4 -> 종료
메뉴에서 4를 입력 받을 때까지 코드는 종료되면 안되고
입력 값은 조건 범위의 숫자만 입력한다고 가정합니다. (예외 처리 필요x)
출력 예시 참고해서 같은 결과가 나오도록 만들면 됩니다.
코드랑 실행 화면 정리해 멘토에게 보내주세요 (구글링X)


과제 1

#include <stdio.h>

int main(void) {
    
    while(1) {
        int menu;
		
        // 메뉴 1, 2, 3, 4
        printf("----------\n");
        printf("1. 마름모 출력\n");
        printf("2. 숫자 거꾸로 출력하기\n");
        printf("3. 소수 판별\n");
        printf("4. 종료\n");
        printf("----------\n");
        printf("메뉴를 선택해주세요 : ");
        scanf("%d", &menu);

	// 마름모 출력
        if (menu == 1) {
            int line;
            printf("마름모의 크기를 입력하세요 : ");
            scanf("%d", &line);

            for (int i=0;i<line;i++) {
                for (int j=line-i-1;j>0;j--) printf(" ");
                for (int k=0;k<2*i+1;k++) printf("*");
                printf("\n");
            }
            for (int x=line-1;x>0;x--) {
                for (int j=line-x;j>0;j--) printf(" ");
                for (int k=0;k<2*x-1;k++) printf("*");
                printf("\n");
            }
        }

	// 숫자 거꾸로 출력하기
        if (menu == 2) {
            int num;
            printf("세자리 이상의 정수를 입력하세요 : ");
            scanf("%d", &num);

            int dec = 10;
            while(num % (dec/10) != num) {
                printf(" %d", num%dec/(dec/10));
                dec *= 10;
            }
            printf("\n");
        }

	// 소수 판별
        if (menu == 3) {
            int prime;
            int test = 0;
            printf("2 이상의 정수를 입력하세요 : ");
            scanf("%d", &prime);

            for (int u=2;u<prime;u++) {
                if (prime%u == 0) {
                    printf("%d은 소수가 아닙니다.\n", prime);
                    test = 1;
                    break;
                }
            }
            if (test == 0) printf("%d은 소수입니다.\n", prime);
        }

	// 종료
        if (menu == 4) {
            printf("종료합니다.");
            break;
        }
    }

    return 0;
}

코드 실행 결과

더보기
----------
1. 마름모 출력
2. 숫자 거꾸로 출력하기
3. 소수 판별
4. 종료
----------
메뉴를 선택해주세요 : 1
마름모의 크기를 입력하세요 : 3
  *  
 *** 
*****
 ***
  *
----------
1. 마름모 출력
2. 숫자 거꾸로 출력하기
3. 소수 판별
4. 종료
----------
메뉴를 선택해주세요 : 2
세자리 이상의 정수를 입력하세요 : 192387
 7 8 3 2 9 1
----------
1. 마름모 출력
2. 숫자 거꾸로 출력하기
3. 소수 판별
4. 종료
----------
메뉴를 선택해주세요 : 3
2 이상의 정수를 입력하세요 : 3
3은 소수입니다.
----------
1. 마름모 출력
2. 숫자 거꾸로 출력하기
3. 소수 판별
4. 종료
----------
메뉴를 선택해주세요 : 3
2 이상의 정수를 입력하세요 : 4
4은 소수가 아닙니다.
----------
1. 마름모 출력
2. 숫자 거꾸로 출력하기
3. 소수 판별
4. 종료
----------
메뉴를 선택해주세요 : 4
종료합니다.

 


 

포인터 개념 조사/ 주어진 코드2개 최대한 이해하려 노력 후 정리!


과제 2

C프로그래밍에서 변수를 설정하면 그 변수는 메모리 공간에 저장된다.

변수가 저장되는 메모리 공간의 주소를 나타내는 변수가 포인터이다.

이때 주소값은 시작 주소만을 의미한다.

 

포인터에서는 주로 주소 연산자(&)와 참조 연산자(*)가 쓰인다.

주소 연산자는 변수 앞에 붙어서 변수의 주소값을 반환한다.

 

int a = 12;
printf("%#x\n", &a);	// 0x61ff18

정수형 변수 a에는 12라는 수가 저장되어 있지만 & 주소 연산자를 사용하여 &a를 출력하면 12가 저장되어 있는 메모리 공간의 주소가 출력된다.

 

int a= 12;
int* pa = &a;

printf("%d\n", *pa);	// 12

pa 포인터에 참조 연산자를 통해서 pa 라는 포인터에 a의 주소값을 저장한다.

참조 연산자를 통해 pa 포인터의 주소값을 역참조하면 해당 주소값에 저장되어 있는 변수인 a의 값인 12가 출력된다.

 

#include <stdio.h>
#include <string.h>
// 문자열 처리 관련 라이브러리 헤더파일 추가

int main(void) {
    char str[] = (" Hello, World!");   // str 배열에 "   Hello, World!" 문자열 저장
    printf("Original: '%s'\n", str);    // Original: " Hello, World!"

    char* begin = str;  // begin 포인터에 str 주소값 시작점 저장
    char* dest = str;   // dest 포인터에 str 주소값 시작점 저장
    while (*begin != '\0' && (*begin == ' ' || *begin == '\t' || *begin == '\n')) {
        begin++;
    }
    // '\0'은 문자열의 끝을 나타낼 때 쓰임
    // 주소값을 시작 주소부터 늘리면서 줄바꿈 or 탭 or 공백이 있는 주소를 찾음
    // 최초로 줄바꿈 or 탭 or 공백이 등장하고 연속적으로 줄바꿈 or 탭 or 공백이 등장할 경우 최종적으로 등장하는 줄바꿈 or 탭 or 공백이 있는 주소가 begin에 저장되고 반복문 break

    if (begin != str) { // 앞에 줄바꿈 or 탭 or 공백으로 시작하지 않으면 begin == str이므로 시행X
        while (*begin != '\0') {    // 문자열이 끝나기 전까지
            *dest++ = *begin++; // begin 주소값에 들어있는 값을 dest 주소값에 저장해서 문자열 밀어내기
        }
        *dest = '\0';   // 문자열 끝나면 dest 포인터가 가리키는 주소에 \0을 저장해 문자열 종료시키기 (끊기 / 자르기)
    }

    printf("trim: '%s'\n", str);    // 최종적으로 변형된 문자열 출력 (앞에 연속적으로 이어지는 줄바꿈, 공백, 탭 모두 제거됨)

    return 0;
}

머릿속으로는 이해되는데 주석으로 달려고 하니까 내가 썼는데도 무슨 말인지 알아먹기 힘들다.

아무튼 예를 들어 "                Hello,           World!   " 이런 문자열을 입력하면 "Hello,           World!   " 이렇게 앞에 있는 공백만 잘려져서 출력이 된다는 말이다.

 

포인터 없이 더 알아보기 쉽도록 코드를 작성할 수도 있지만 왜 굳이 포인터로 구현했는지는 잘 모르겠다.

가독성을 버리고 코드의 효율성을 챙긴 것일 수도 있고, 나중에 배울 리버싱을 연습시키기 위한 것일 수도 있을 것 같다.

728x90
반응형

댓글