c

c 언어 문제

haniru 2025. 11. 14. 23:50
#include <stdio.h>
#include <math.h>

int main() {
	
	for (int i = 2; i <= 100; i++) {
		int prime_count = 0;

		for (int j = 1; j <= sqrt(i); j++) {
			if (i % j == 0) {
				prime_count++;
			}

			if (prime_count > 1) {
				break;
			}
		}
		if (prime_count == 1) {
			printf("%d ", i);
		}
	}

	return 0;
}

삼각형 넓이 구하기

#include <stdio.h>

int main()
{
    int width = 10, height = 20;
    
    printf("넓이는 %d 입니다\n", (width * height)/2);
    
    return 0;
}

 

1~100 합계구하기

#include <stdio.h>

int main() {
	int sum = 0;

	for (int i = 1; i <= 100; i++) {
		sum += i;
	}
	printf("%d\n", sum);

	return 0;
}

 

시험점수 구하기

#include <stdio.h>
#include <stdlib.h>

int main() {
	int N = 0;
	printf("점수를 입력해주세요(0~100): ");
	scanf("%d", &N);

	if (N < 0 || N > 100) {
		printf("0~100 까지만 입력해주세요.\n");
		exit(1); // exit(1)이 호출되면 프로그램은 즉시 종료된다
	}

	if (N >= 90) {
		printf("A학점입니다.\n");
	}
	else if (N >= 80) {
		printf("B학점입니다.\n");
	}
	else if (N >= 70) {
		printf("C학점입니다.\n");
	}
	else if (N >= 60) {
		printf("D학점입니다.\n");
	}
	else {
		printf("F학점입니다.\n");
	}

	return 0;
}

 

 

두 수 바꾸기 (call by reference)

두 개의 정수포인터(int*)를 인수로 받는다. 이는 두 변수의 메모리 주소를 전달받는다.

#include <stdio.h>
#include <stdlib.h>

void swap(int* num1, int* num2);

int main() {
	int a, b;
	printf("두 정수를 입력해주세요(1~10000): ");

	scanf("%d %d", &a, &b);

	swap(&a, &b);

	printf("%d %d\n", a, b);

	return 0;
}

void swap(int* num1, int* num2) {
	int temp = *num1;
	*num1 = *num2;
	*num2 = temp;
}

 

구구단 구하기 (9단부터 2단)

#include <stdio.h>

int main() {
	for (int i = 9; i >= 2; i--) {
		for (int j = 1; j <= 9; j++) {
			printf("%d * %d =  %d\n", i, j, i * j);
		}
	}
	return 0;
}

 

알파벳 대문자, 알파벳 소문자, 숫자, 특수문자 구하기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
	char* str = malloc(sizeof(char) * 1000); // stdlib.h 를 사용해야 한다
	printf("문자열을 입력해주세요: ");
	fgets(str, 1000, stdin);
// 	scanf("%s", str);

	int big_count = 0;
	int small_count = 0;
	int num_count = 0;
	int special_count = 0;

	for (int i = 0; i < strlen(str); i++) {
		char s = str[i];

		if (s >= 'A' && s <= 'Z') {
			big_count++;
		}
		else if (s >= 'a' && s <= 'z') {
			small_count++;
		}
		else if (s >= '0' && s <= '9') {
			num_count++;
		}
		else if (s != '\n') {
			special_count++;
		}
// 		else { // scanf 는 개행 문자가 안들어간다
// 			special_count++;
// 		}
	}

	printf("알파벳 대문자 : %d\n", big_count);
	printf("알파벳 소문자 : %d\n", small_count);
	printf("숫자 : %d\n", num_count);
	printf("특수문자 : %d\n", special_count);
	return 0;
}

 

개선버

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

int main() {
    char* str = (char*)malloc(sizeof(char) * 1000);
    
    if (str == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }
    
    printf("문자열을 입력해주세요: ");
    fgets(str, 1000, stdin);
    
    str[strcspn(str, "\n")] = '\0';
    
    int upper_count = 0;
    int lower_count = 0;
    int digit_count = 0;
    int special_count = 0;
    
    for (int i=0; str[i] != '\0'; i++) {
        char s = str[i];
        
        if (isupper(s)) {
            upper_count++;
        } else if (islower(s)) {
            lower_count++;
        } else if (isdigit(s)) {
            digit_count++;
        } else {
            special_count++;
        }
    }
    
    printf("알파벳 대문자: %d\n", upper_count);
    printf("알파벳 소문자: %d\n", lower_count);
    printf("숫자: %d\n", digit_count);
    printf("특수문자: %d\n", special_count);
    
    free(str);
    
    retrun 0;
}

 

소수 구하기

 

틀린버전: 소수는 약수가 1과 자기자신 총 2개이다. 근데 로직은 sqrt(i) 까지 약수 갯수로만 판별하고 있어 맞지 않다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <math.h>

int main() {
	
	for (int i = 2; i < 100; i++) {
		int prime_count = 0;

		for (int j = 1; j <= sqrt(i); j++) {
			if (i % j == 0) {
				prime_count++;
			}

			if (prime_count > 1) {
				break;
			}
		}
		if (prime_count == 1) {
			printf("%d ", i);
		}
	}

	return 0;
}

 

정답: 약수의 갯수를 세지 않고, 1 이외의 약수가 존재하는지 판별한다. 2부터 시작해서 약수가 발견되면 즉시 종료한다.

#include <stdio.h>
#include <math.h>

int main() {
	
	for (int i = 2; i <= 100; i++) {
		int is_prime = 1;

		for (int j = 2; j <= sqrt(i); j++) {
			if (i % j == 0) {
				is_prime = 0;
				break;
			}
		}
		
		if (is_prime == 1) {
			printf("%d ", i);
		}
	}

	return 0;
}

 

완전수 구하기

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

int main() {
	int num = 0;
	int sum = 0;
	printf("정수를 입력해주세요: ");
	scanf("%d", &num);

	for (int i = 1; i <= num/2; i++) {
		if (num % i == 0) {
			sum += i;
		}
	}

	if (sum == num) {
		printf("yes");
	}
	else {
		printf("no");
	}

	return 0;
}

 

마름모 그리기

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

int main() {
	int N = 0;
	printf("정수를 입력해주세요(50 이하의 홀수): ");
	scanf("%d", &N);

	int half = N / 2;

	for (int r = 0; r < N; r++) {
		int start = half;
		int end = half;

		if (r > half) {
			start = r - half;
			end = half + (N-r-1);
		}
		else {
			start = half - r;
			end = half + r;
		}

		for (int c = 0; c < N; c++) {
			if (c >= start && c <= end) {
				printf("*");
			}
			else {
				printf(" ");
			}
		}
		printf("\n");
	}

	return 0;
}

 

마방진

헷갈렸던 부분

n/2: 왜 (n-1)/2가 아니냐면 홀수이기 때문에

행은 아래로, 열은 왼쪽으로 이동하는 부분: 반대 방향으로 생각함

이미 채워져 있을 때: 행만 아래로 내려가야하는데, 행은 위로 열은 오른쪽으로 생각함

#include <stdio.h>
#include <stdlib.h>

int main() {
	int n;
	printf("홀수 n을 입력해주세요: ");
	if(scanf("%d", &n) != 1 || n % 2 == 0 || n <= 0) {
	    printf("올바른 홀수를 입력해주세요\n");
	    return 1;
	}

	int arr[100][100] = { 0, };
	
	int total = n * n;
	int current_num = 1;
	
	int r = 0;
	int c = n/2; // 홀수이기 때문에

	arr[r][c] = current_num;
	
	// 첫 행 
	while (current_num < total) {
	    int next_r = r - 1;
	    int next_c = c + 1;
	    
	    // 맨 아래행으로 이동
	    if (next_r < 0) {
	        next_r = n - 1;
	    }
	    
	    // 맨 왼쪽열로 이동
	    if (next_c >= n) {
	        next_c = 0;
	    }
	    
	    if (arr[next_r][next_c] != 0) {
	        // 이미 채워져 있을때
			next_r = r + 1;
			next_c = c;
		}
		
		current_num++;
		r = next_r;
		c = next_c;
		arr[r][c] = current_num;
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}

	return 0;
}

 

문자열 역순 출력

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

int main() {
	char str[1000];

	printf("문자열을 입력해주세요: ");
	scanf("%s", str);

	for (int i = (strlen(str)-1); i>=0 ; i--) {
		printf("%c", str[i]);
	}

	return 0;
}

 

난수 생성

원래는 int number = rand() % 11;

if (number == 0) number++; 를 사용했는데 아래 코드가 맞다고 한

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // srand, rand 함수를 위해 필요
#include <time.h>   // time 함수를 위해 필요

int main() {
	int arr[10];
	// 1. 시드 초기화 (time.h를 포함해야 함)
	srand((unsigned int)time(NULL)); 

	for (int i = 0; i < 10; i++) {
        // 2. 난수 생성 수정: 0~9 범위에 +1을 하여 1~10 범위의 균일 난수 생성
		int number = (rand() % 10) + 1; 

		arr[i] = number;
	}

	printf("생성된 난수: ");
	for (int i = 0; i < 10; i++) {
		printf("%d ", arr[i]);
	}
    printf("\n");
    
	return 0; // main 함수는 return 0으로 끝내는 것이 좋습니다.
}

 

로또번호 생성

헷갈렸던 부분: 중복 확인을 따로 안했음

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

bool is_duplicate(int arr[], int size, int number) {
    bool result = false;
    for (int i=0; i<size; i++) {
        if (arr[i] == number) {
            result = true;
            break;
        }
    }
    
    return result;
}

int main() {
    int lotto_numbers[7];
    int count = 0;
    
    srand((unsigned int)time(NULL));
    
    while (count < 7) {
        int number = (rand() % 45) + 1;
        
        if (!is_duplicate(lotto_numbers, count, number)) {
            lotto_numbers[count] = number;
            count++;
        }
    }
    
    printf("로또 번호 : ");
    for (int i=0; i<6; i++) {
        printf("%d ", lotto_numbers[i]);
    }
    printf("\n보너스 번호: ");
    printf("%d\n", lotto_numbers[6]);
    
    return 0;
}

 

데이터 삽입/삭제/조회/수정/종료

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int menu;

	printf("1. 데이터 삽입\n");
	printf("2. 데이터 삭제\n");
	printf("3. 데이터 조회\n");
	printf("4. 데이터 수정\n");
	printf("5. 프로그램 종료\n");

	while (1) {
		printf("메뉴: ");
		scanf("%d", &menu);

		if (menu == 5) {
			printf("프로그램이 종료됩니다.\n");
			break;
		}
	}

	return 0;
}

 

달팽이 배열

이거는 여러번 봐야할 것 같다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

void print_snail_array(int n);

int main() {
    int n;
    printf("달팽이 배열의 크기(n)를 입력하세요: ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("유효한 양의 정수를 입력하세요.\n");
        return 1;
    }
    
    print_snail_array(n);

    return 0;
}

void print_snail_array(int n) {
    // 배열 선언 (n이 100보다 크면 오류 발생 가능성 있음, 동적 할당 권장)
    int arr[100][100] = {0,}; 
    
    // 현재 행(r), 열(c) 위치와 채워넣을 숫자
    int r = 0;
    int c = 0;
    int num = 1;
    
    // 경계 설정: 현재 채울 수 있는 배열의 영역
    int min_r = 0, max_r = n - 1; // 최소/최대 행 인덱스
    int min_c = 0, max_c = n - 1; // 최소/최대 열 인덱

    // 총 N*N개의 숫자를 모두 채울 때까지 반복
    while (num <= n * n) {
        
        // 1. ➡️ 오른쪽으로 채우기 (열 증가)
        // 현재 행(r)은 min_r로 고정, min_c부터 max_c까지 채움
        for (c = min_c; c <= max_c; c++) {
            if (num > n * n) break;
            arr[r][c] = num++;
        }
        // 다음 회전을 위해 경계 좁히기: 맨 윗 행(min_r)은 다 썼으니 다음 줄로 내림
        min_r++; 
        r = min_r; // 현재 위치를 다음 줄의 시작 행으로 이동
        c = max_c; // 현재 열 위치는 맨 오른쪽 열(max_c)로 유지
        
        // 2. ⬇️ 아래쪽으로 채우기 (행 증가)
        // 현재 열(c)은 max_c로 고정, min_r부터 max_r까지 채움
        for (r = min_r; r <= max_r; r++) {
            if (num > n * n) break;
            arr[r][c] = num++;
        }
        // 다음 회전을 위해 경계 좁히기: 맨 오른쪽 열(max_c)은 다 썼으니 왼쪽으로 당김
        max_c--; 
        c = max_c; // 현재 위치를 다음 줄의 시작 열로 이동
        r = max_r; // 현재 행 위치는 맨 아래 행(max_r)로 유지
        
        // 3. ⬅️ 왼쪽으로 채우기 (열 감소)
        // 현재 행(r)은 max_r로 고정, max_c부터 min_c까지 채움
        for (c = max_c; c >= min_c; c--) {
            if (num > n * n) break;
            arr[r][c] = num++;
        }
        // 다음 회전을 위해 경계 좁히기: 맨 아래 행(max_r)은 다 썼으니 위로 올림
        max_r--; 
        r = max_r; // 현재 위치를 다음 줄의 시작 행으로 이동
        c = min_c; // 현재 열 위치는 맨 왼쪽 열(min_c)로 유지
        
        // 4. ⬆️ 위쪽으로 채우기 (행 감소)
        // 현재 열(c)은 min_c로 고정, max_r부터 min_r까지 채움
        for (r = max_r; r >= min_r; r--) {
            if (num > n * n) break;
            arr[r][c] = num++;
        }
        // 다음 회전을 위해 경계 좁히기: 맨 왼쪽 열(min_c)은 다 썼으니 오른쪽으로 당김
        min_c++; 
        c = min_c; // 현재 위치를 다음 줄의 시작 열로 이동
        r = min_r; // 현재 행 위치는 맨 윗 행(min_r)으로 유지 (다음 오른쪽 이동 준비)
    }

    // 결과 출력
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%4d", arr[i][j]); // 4자리 폭으로 정렬 출력
        }
        printf("\n");
    }
}

'c' 카테고리의 다른 글

입출력, 매크로, wsl  (0) 2025.11.17
파일처리  (0) 2025.11.13
구조체  (0) 2025.11.12
배열, 포인터와 구조  (0) 2025.11.11
이중포인터 N차원 배열  (1) 2025.11.10