14 분 소요

“#define NULL ((void *)0)”에 대해서(지난 복습)

이 코드는 C나 C++ 프로그래밍에서 NULL포인터를 정의하는 매크로입니다. 이 매크로는 보통 포인터가 가리키는 대상이 없음을 나타내는데 사용된다.

여기서, NULL은 포인터가 아무것도 가리키지 않음을 나타내기 위해 0으로 정의되어 있다고 한다. 일반적으로, NULL은 포인터가 유효한 주소를 가지고 있지 않다는 것을 나타내기 위해 사용됩니다. 코드에서 포인터 초기화 또는 비교 시 NULL을 사용하여 특정조건을 나타내는 것이 일반적입니다.

이 매크로를 사용함으로써 코드의 가독성을 높이고, 포인터와 관련된 코드에서 일관성을 유지할 수 있습니다. ((void *)0) 부분은 NULL을 void포인터로 캐스팅하는 것을 나타내며, 포인터의 타입에 따라 다르게 정의될 수 있습니다. C표준에 따르면, NULL은 어떤 포인터 타입에도 가능한 상수로 정의되어야 합니다.

필기시험1)이중포인터(3_11)

#include <stdio.h>

int main() {
    int i = 100;
    int* pi = &i; //포인터 선언
    int** dpi = &pi; //이중 포인터 선언

    printf("%p %p %p\n", (void*)&i, (void*)pi, (void*)*dpi);

    *pi = i + 30;
    printf("%d %d %d\n", i, *pi, **dpi);

    **dpi = *pi + 30;
    printf("%d %d %d\n", i, *pi, **dpi);

    return 0;
}

코드리뷰:

pdf에는 (void*)이 붙여져 있지만 엄격하게 구분하면 붙여주는게 맞다고 한다. 이렇게 캐스팅을 해주어야 제 2의 타입으로 형변환을 해주는게 없다는 것을 명시해줄 필요가 있다고 한다.

-(void*)&i : 정수변수 i의 주소를 출력합니다.

-(void*)pi : 포인터 pi가 가리키는 주소를 출력합니다.

-(void*) *dpi : 이중포인터 dpi가 가리키는 주소를 출력합니다.

필기시험2)간접연산자와 증감연산자 활용(3_11)

#include <stdio.h>

int main() {
    int a[] = { 10, 20 };
    int* p = &a[0];

    printf("%d\n", *p++); //(1)
    printf("%d\n", *p);   //(2)

    p = &a[0];
    printf("%d\n", *p++);
    printf("%d\n\n", *p);

    p = &a[0];
    printf("%d\n", (*p)++);//10 꺼내오고 그거에 1 더해줘
    printf("10에 1 더해줘%d\n", *p);

    a[0] = 10;
    p = &a[0];
    printf("%d\n", ++ * p);//++(*p)와 동일
    printf("%d\n\n", *p);

    return 0;
}

코드리뷰:

(1)포인터에서 참조하고 한칸 이동

(2)한칸 이동한 포인터에서 참조

(3)포인

원소의 주소와 다양한 접근방법

#include <stdio.h>

int main() {
    int a[3] = { 5, 10, 15 };
    int* p = a; // a = &a[0]

    //포인터 변수 p사용, 배열 원소 값 참조
    printf("%d %d %d\n", *(p), (long*)*(p + 1), (double*)*(p + 2));
    //위 포인터 변수 p에서 배열처럼 첨자를 사용 가능
    printf("%d %d %d\n", p[0], p[1], p[2]);

    return 0;
}

배열이름과 간접연산자로 참조(3_11)

image-20240109095850358

#include <stdio.h>

int main() {
    int td[2][3] = { {1, 2, 3},{4, 5, 6} };

    printf("%u\n", sizeof(td));
    printf("%u %u\n", sizeof(td[0]), sizeof(td[1]));
    printf("%u %u\n", sizeof(*td), sizeof(*(td + 1)));

    **(td+0) = 10;
    *(*td + 4) = 20;
    *(*(td + 1) + 2) = 30;
    printf("%d %d %d\n", td[0][0], td[1][1], td[1][2]);

    return 0;
}

output>

24 12 12 12 12 10 20 30

2차원 배열 포인터 선언

expression(1)

#include <stdio.h>
#define ROWS 2
#define COLS 3

void doubleElements(int arr[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            arr[i][j] *= 2;
        }
    }
}
int main() {
    int arr[ROWS][COLS] = { {1,2,3},{4,5,6} };
    doubleElements(arr);

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

여기서는 2차원 배열의 행과 크기를 일일이 지정해주고 거기에 값을 넣는 형식으로 가장 직관적인 표현입니다. 하지만 그 다음표현은 조금 다릅니다.

expression(2)

#include <stdio.h>
#define COLS 3

void doubleElements(int (*ptr)[COLS], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < COLS; j++) {
            ptr[i][j] *= 2;
        }
    }
}
int main() {
    int arr[2][COLS] = { {1,2,3},{4,5,6} };
    doubleElements(arr,2);

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

직접 배열을 참조해오는 첫번째 함수 표현식과 달리 두번째 함수 표현식에서는 간접적으로 배열을 참조해오는 방식입니다.

두 코드의 출력결과는 다음과 같다.

2 4 6 8 10 12

지금까지는 “배열 포인터”에 대해 알아봤다면 이번에는 “포인터 배열”이다.

포인터 배열을 왜 쓸까?

문자형 배열에 다음과 같이 저장해서 출력할 수 있겠다.

#include <stdio.h>
#define COLS 3


int main() {
    char days[7] = {
        'M', 'T', 'W',
        'T', 'F', 'S', 'S'
    };

    for (int i = 0; i < 7; i++)
    {
        printf("%c  ", days[i]);
    }

    return 0;
}

위와 같이 문자(char)를 각 1바이트씩 저장해서 출력하는게 가능하다. 그러면 문자열형 배열도 구현해보자!

#include <stdio.h>
#define COLS 3


int main() {
    char days[7] = {
        "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday", "Sunday"
    };

    for (int i = 0; i < 7; i++)
    {
        printf("%s\n", days[i]);
    }

    return 0;
}

위와 같이 짜고 돌리면 당연히 문제가 생긴다.

-데이터 타입에 대한 이슈: char는 각 원소에 문자하나밖에 저장하지 못한다. 그래서

이니셜라이저가 너무 많습니다.

라는 에러문장이 뜨게 된다.

그래서 우리한테 남은 선택지는 단 하나다 바로 포인터 배열을 사용하는 방식이다.

함수 malloc()에 의한 배열 공간 할당

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int n = 0;
    printf("입력할 점수의 개수를 입력 >> ");
    scanf("%d", &n);

    int* ary = NULL;
    if ((ary = (int*)malloc(sizeof(int) * n)) == NULL)
    {
        printf("메모리 할당에 문제가 있습니다.");
        exit(1);
    };

    printf("%d개의 점수 입력>> ", n);
    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", (ary + i));
        sum += *(ary + i);
    }

    printf("입력 점수: ");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", *(ary + i));
    }
    printf("\n");
    printf("합: %d 평균: %.1f\n", sum, (double)sum / n);
    return 0;
}

근데 위 코드가 제대로 동작하지 않아 아래와 같이 바꿨다.

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

int main() {
    int size;

    // 사용자로부터 배열의 크기를 입력 받음
    printf("Enter the size of the array: ");
    scanf("%d", &size);

    // malloc 함수를 사용하여 동적으로 메모리를 할당
    int* dynamicArray = (int*)malloc(size * sizeof(int));

    // 메모리 할당이 성공했는지 확인
    if (dynamicArray == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        return 1; // 프로그램 종료, 오류 코드 1 반환
    }

    // 배열에 값 할당
    printf("Enter %d integers:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &dynamicArray[i]);
    }

    // 할당한 배열의 값 출력
    printf("Entered integers: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", dynamicArray[i]);
    }

    // 할당한 메모리 해제
    free(dynamicArray);

    return 0;
}

함수 calloc()

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

int main() {
    int size;

    // 사용자로부터 배열의 크기를 입력 받음
    printf("Enter the size of the array: ");
    scanf("%d", &size);

    // calloc 함수를 사용하여 동적으로 메모리를 할당
    int* dynamicArray = (int*)calloc(size, sizeof(int));

    // 메모리 할당이 성공했는지 확인
    if (dynamicArray == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        return 1; // 프로그램 종료, 오류 코드 1 반환
    }

    // 배열에 값 할당
    printf("Enter %d integers:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &dynamicArray[i]);
    }

    // 할당한 배열의 값 출력
    printf("Entered integers: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", dynamicArray[i]);
    }

    // 할당한 메모리 해제
    free(dynamicArray);

    return 0;
}

함수 realloc()

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

int main() {
    int num_elements;
    int* array;

    printf("Enter the number of elements: ");
    scanf("%d", &num_elements);

    array = (int*)malloc(num_elements * sizeof(int));
    if (array == NULL) {
        printf("Error allocating memory!\n");
        return 1;
    }
    for (int i = 0; i < num_elements; i++)
    {
        array[i] = i;
    }
    for (int i = 0; i < num_elements; i++)
    {
        printf("%d ", array[i]);
    }

    //Resize the array with realloc
    num_elements *= 2;
    array = (int*)realloc(array, num_elements * sizeof(int));
    if (array == NULL) {
        printf("Error allocating memory!\n");
        return 1;
    }
    //Initialize the new elements in the array
    for (int i = num_elements / 2; i < num_elements; i++)
    {
        array[i] = i;
    }
    for (int i = 0; i < num_elements; i++)
    {
        printf("%d ", array[i]);
    }
    printf("\n");

    free(array);

    return 0;
}

lab 실습문제

문제1

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

int main() {
    int size;

    // 사용자로부터 배열의 크기를 입력 받음
    printf("Enter the size of the array: ");
    scanf("%d", &size);

    // malloc 함수를 사용하여 동적으로 메모리를 할당
    float* dynamicArray = (int*)malloc(size * sizeof(int));
    float* dynamicArray2 = (int*)malloc(size * sizeof(int));

    // 메모리 할당이 성공했는지 확인
    if (dynamicArray == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        return 1; // 프로그램 종료, 오류 코드 1 반환
    }
    if (dynamicArray2 == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        return 1; // 프로그램 종료, 오류 코드 1 반환
    }

    // 배열에 값 할당(1)
    printf("Enter %d integers:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%f", &dynamicArray[i]);
    }

    // 배열에 값 할당(1)
    printf("Enter %d integers:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%f", &dynamicArray2[i]);
        dynamicArray[i] += dynamicArray2[i];
    }

    // 할당한 배열의 값 출력
    printf("Entered integers: ");
    for (int i = 0; i < size; i++) {
        printf("%.2f ", dynamicArray[i]);
    }

    // 할당한 메모리 해제
    free(dynamicArray);
    free(dynamicArray2);

    return 0;
}

위 코드는 요구조건을 지키지 않았다. 조건에서 언급한 함수를 기재하고 파일에서 값을 입력받도록 하자.

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

void add_array(double source1[], double source2[], double target[], int num) {
    for (int i = 0; i < num; i++) {
        target[i] = source1[i] + source2[i];
    }
}

int main() {
    FILE* file;
    int size;

    // 파일 열기
    if ((file = fopen("f1.txt", "r")) == NULL) {
        printf("파일이 열리지 않습니다.\n");
        exit(1);
    }

    // 배열의 크기를 파일에서 읽어옴
    fscanf(file, "%d", &size);

    // 동적 메모리 할당
    double* dynamicArray1 = (double*)malloc(size * sizeof(double));
    double* dynamicArray2 = (double*)malloc(size * sizeof(double));
    double* sumArray = (double*)malloc(size * sizeof(double));

    // 메모리 할당이 성공했는지 확인
    if (dynamicArray1 == NULL || dynamicArray2 == NULL || sumArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1);
    }

    // 첫 번째 배열에 값 할당
    printf("Enter %d floating-point numbers for the first array:\n", size);
    for (int i = 0; i < size; i++) {
        fscanf(file, "%lf", &dynamicArray1[i]);
    }

    // 두 번째 배열에 값 할당
    printf("Enter %d floating-point numbers for the second array:\n", size);
    for (int i = 0; i < size; i++) {
        fscanf(file, "%lf", &dynamicArray2[i]);
    }

    // 두 배열의 합 계산
    add_array(dynamicArray1, dynamicArray2, sumArray, size);

    // 결과 출력
    printf("\nSum of Arrays:\n");
    for (int i = 0; i < size; i++) {
        printf("%.2lf ", sumArray[i]);
    }

    // 할당한 메모리 해제
    free(dynamicArray1);
    free(dynamicArray2);
    free(sumArray);

    // 파일 닫기
    fclose(file);

    return 0;
}

문제2

int* buildArray();를 사용하라고 한걸로 보아 값을 입력받는 것은 이 함수의 구현부 내에서 처리를 해야 하고,

반환데이터를 포인터배열, 즉 배열이어야 한다는 것이다.

참조코드(1): int* buildArray()구현하고 출력하기

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

int size;

int* buildArray() {
    

    // 사용자로부터 배열의 크기를 입력 받음
    scanf("%d", &size);

    int* dynamicArray = (int*)malloc(size * sizeof(int));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1); // 오류 코드 1로 프로그램 종료
    }

    printf("%d개의 정수를 입력하세요:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &dynamicArray[i]);
    }

    return dynamicArray;
}

int main() {
    // buildArray 함수를 사용하여 배열 생성
    int* dynamicArray = buildArray();

    // 입력된 정수 출력
    printf("입력된 정수: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", dynamicArray[i]);
    }

    // 할당한 메모리 해제
    free(dynamicArray);

    return 0;
}

참조코드(2): 배열 입력받고 최소값 출력하기

int findMin(int* ary)
{
    int min;
    min = ary[0];

    for (int i = 1; i < size; i++)
    {
        if (min > ary[i])
        {
            min = ary[i];
        }
    }
    return min;
}

CI(1)

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

int size;

int* buildArray() {
    

    // 사용자로부터 배열의 크기를 입력 받음
    printf("배열의 크기를 입력하세요:\n", size);
    scanf("%d", &size);

    int* dynamicArray = (int*)malloc(size * sizeof(int));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1); // 오류 코드 1로 프로그램 종료
    }

    printf("%d개의 정수를 입력하세요:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &dynamicArray[i]);
    }

    return dynamicArray;
}
int findMin(int* ary)
{
    int min;
    min = ary[0];

    for (int i = 1; i < size; i++)
    {
        if (min > ary[i])
        {
            min = ary[i];
        }
    }
    return min;
}
int main() {
    // buildArray 함수를 사용하여 배열 생성
    int* dynamicArray = buildArray();

    printf("%d", findMin(dynamicArray));
    // 할당한 메모리 해제
    free(dynamicArray);

    return 0;
}

파일 열지 않았음… 다시 해야함. 파일열어서 값 옮기는 코드는 공통적인 거니까 그냥 참조코드 마지막에 하나 만들어서 통합시키는 방향으로 하자.

최종CI

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

int size;

float* buildArray() {
    FILE* f;
    if (fopen_s(&f, "f2.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    };

    // 배열의 크기를 파일에서 읽어옴
    fscanf(f, "%d", &size);

    // 동적 메모리 할당
    float* dynamicArray = (float*)malloc(size * sizeof(float));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1);
    }

    int cnt = 0;
    float ch;

    while (fscanf(f, "%f", &ch) != EOF) {
        if (cnt < size) {
            dynamicArray[cnt] = ch;
            cnt++;
        }
    }

    return dynamicArray;
}

float findMin(float* ary) {
    float min;
    min = ary[0];

    for (int i = 1; i < size; i++) {
        if (min > ary[i]) {
            min = ary[i];
        }
    }
    return min;
}

int main() {
    float* dynamicArray = buildArray();

    printf("%0.f", findMin(dynamicArray));

    // 동적 할당된 메모리 해제
    free(dynamicArray);

    return 0;
}

문제3

참조코드(1): 퀵정렬

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

int values[] = { 40, 10, 100, 90, 20, 25 };
int compare(const void* a, const void* b)
{
    return (*(int*)a - *(int*)b);
}

int main() {
    int n;
    qsort(values, 6, sizeof(int), compare);
    for (n = 0; n < 6; n++)
        printf("%d ", values[n]);

    return 0;
}

참조코드(2): int* buildArray()구현하고 출력하기

int size;  //전역변수
...
int* buildArray() {

    // 사용자로부터 배열의 크기를 입력 받음
    printf("배열의 크기를 입력하세요:\n", size);
    scanf("%d", &size);

    int* dynamicArray = (int*)malloc(size * sizeof(int));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1); // 오류 코드 1로 프로그램 종료
    }

    printf("%d개의 정수를 입력하세요:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &dynamicArray[i]);
    }

    return dynamicArray;
}
...
int main() {
    // buildArray 함수를 사용하여 배열 생성
    int* dynamicArray = buildArray();
    return 0;
}

CI(1) = 참조(1) + 참조(2)

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

int size;

int* buildArray() {

    // 사용자로부터 배열의 크기를 입력 받음
    printf("배열의 크기를 입력하세요:\n", size);
    scanf("%d", &size);

    float* dynamicArray = (float*)malloc(size * sizeof(float));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1); // 오류 코드 1로 프로그램 종료
    }

    printf("%d개의 정수를 입력하세요:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%f", &dynamicArray[i]);
    }

    return dynamicArray;
}

int compare(const void* a, const void* b) {
    return (*(float*)a - *(float*)b);
}

int main() {
    int n;
    // buildArray 함수를 사용하여 배열 생성
    float* dynamicArray = buildArray();
    qsort(dynamicArray, size, sizeof(float), compare);
    for (n = 0; n < size; n++)
        printf("%.1f ", dynamicArray[n]);

    return 0;
}

참조(3):어제 실습문제 4번:n개의 정수를 입력받아 배열에 저장하고, 최대,최소 구하기

다만, 기존코드는 정수버전이라 실수버전으로 변형했다.

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

int size;

float* buildArray() {
    FILE* f;
    if (fopen_s(&f, "f3.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    };

    // 배열의 크기를 파일에서 읽어옴
    fscanf(f, "%d", &size);

    // 동적 메모리 할당
    float* dynamicArray = (float*)malloc(size * sizeof(float));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1);
    }

    int cnt = 0;
    float ch;

    while (fscanf(f, "%f", &ch) != EOF) {
        if (cnt < size) {
            dynamicArray[cnt] = ch;
            cnt++;
        }
    }

    for (int i = 0; i < size; i++) {
        printf("%.1f ", dynamicArray[i]);
    }

    return dynamicArray;
}



int main() {
    float* dynamicArray = buildArray();
    
    //...

    // 동적 할당된 메모리 해제
    free(dynamicArray);

    return 0;
}

“f3.txt”에 있는 내용>

8.1 1.3 7.5 2.2 -4.7

console_output>

8.1 1.3 7.5 2.2 -4.7

위 코드를 참고하여 다음과 같이 짰다.

CI(2) =CI(1) + 참조(3)

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

int size;

float* buildArray() {
    FILE* f;
    if (fopen_s(&f, "f3.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    };

    // 배열의 크기를 파일에서 읽어옴
    fscanf(f, "%d", &size);

    // 동적 메모리 할당
    float* dynamicArray = (float*)malloc(size * sizeof(float));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1);
    }

    int cnt = 0;
    float ch;

    while (fscanf(f, "%f", &ch) != EOF) {
        if (cnt < size) {
            dynamicArray[cnt] = ch;
            cnt++;
        }
    }

   

    return dynamicArray;
}

int compare(const void* a, const void* b) {
    return (*(float*)a - *(float*)b);
}


int main() {
    float* dynamicArray = buildArray();
    qsort(dynamicArray, size, sizeof(float), compare);
 
    for (int n = 0; n < size; n++)
        printf("%.1f ", dynamicArray[n]);


    // 동적 할당된 메모리 해제
    free(dynamicArray);

    return 0;
}

당연히 예상결과가 나올 줄 알았지만, 그렇지 않았다.

output>

-4.7 2.2 1.3 7.5 8.1 //2.2가 1.3보다 앞에 와있다ㅜㅠ

ChatGPT로 분석해보니,

정수형 정렬에서는 위 int compare(const void* a, const void* b)를 사용해줘도 된다. 하지만 실수형 정렬에서는 얘기가 다르다(이 뭔???)

본론부터 말하자면, “<부동소수점 정밀도="" 문제="">로 인한 정렬문제 오작동"이라 볼 수 있겠다.

compare함수를 보면 첫번째 인자가 두번째 인자보다 작으면 음수를, 크면 양수를, 같으면 0을 반환해야 한다. 그러나 현재의 함수에서는 두 float값을 뺀 값을 반환하고 있어 부동 소수점 정밀도 문제가 발생할 수 있다.

최종 CI

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

int size;

float* buildArray() {
    FILE* f;
    if (fopen_s(&f, "f3.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    };

    // 배열의 크기를 파일에서 읽어옴
    fscanf(f, "%d", &size);

    // 동적 메모리 할당
    float* dynamicArray = (float*)malloc(size * sizeof(float));

    if (dynamicArray == NULL) {
        fprintf(stderr, "메모리 할당 실패.\n");
        exit(1);
    }

    int cnt = 0;
    float ch;

    while (fscanf(f, "%f", &ch) != EOF) {
        if (cnt < size) {
            dynamicArray[cnt] = ch;
            cnt++;
        }
    }

   

    return dynamicArray;
}

int compare(const void* a, const void* b) {
    if (*(float*)a < *(float*)b) return -1;
    if (*(float*)a > *(float*)b) return 1;
    return 0;
}

int main() {
    float* dynamicArray = buildArray();
    qsort(dynamicArray, size, sizeof(float), compare);
 
    for (int n = 0; n < size; n++)
        printf("%.1f ", dynamicArray[n]);


    // 동적 할당된 메모리 해제
    free(dynamicArray);

    return 0;
}

문제4

참조코드(1): 파일열기

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

int main(void)
{
    FILE* f;
    if (fopen_s(&f, "f4.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    }

    int ch;
    while ((ch = fgetc(f)) != EOF)
    {
        putchar(ch);
    }

    printf("\n");
    fclose(f);

    return 0;
}

참조코드(2): 4행5열 배열 생성하기

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

int main(void)
{
    int rows = 4;
    int cols = 5;
    int i, j;

    int** array = (int**)malloc(rows * sizeof(int*));
    if (array == NULL)
    {
        fprintf(stderr, "Memory allocation failed for rows\n");
        return 1;
    }

    for (i = 0; i < rows; i++)
    {
        array[i] = (int*)malloc(cols * sizeof(int));
    }
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            array[i][j] = i * cols + j;
        }
    }
    printf("2D Array Elements:\n");
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }

    //메모리 해제
    for (i = 0; i < rows; i++)
    {
        free(array[i]); //각 행 해제
    }
    free(array);        // 포인터 배열 해제
    return 0;
}

첫번째 CI

#pragma warning(disable : 4996)
#include <stdio.h>
#include <stdlib.h>


void print2DArray(int** d, int rows, int cols)
{
    printf("\n after print2DArray()\n");
    int i, j;
    
    i = 1;
    for (j = 0; j < cols; j++)
    {
        printf("%d ", d[i][j]);
    }
    printf("\n");

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

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

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

int main(void)
{
    FILE* f;
    if (fopen_s(&f, "f4.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    }
    // 포인터 배열 선언
    int i=0, rows = 4, cols = 5;
    int** a = (int**)malloc(rows * sizeof(int*));
    if (a == NULL)
    {
        fprintf(stderr, "Memory allocation failed for rows\n");
        return 1;
    }
    for (i = 0; i < rows; i++)
    {
        a[i] = (int*)malloc(cols * sizeof(int));
    }

    // 문자 체크

    int ch, currentNumber=0;
    int j = 0, k = 0;
    while ((ch = fgetc(f)) != EOF)
    {
        if (isdigit(ch))
        {
            currentNumber = currentNumber * 10 + (ch - '0');
        }
        else if (ch == ' ')
        {
            a[j][k] = currentNumber;
            k++;
            currentNumber = 0;
        }
        else if (ch == '\n')
        {
            a[j][k] = currentNumber;
            j++;
            k = 0;
            currentNumber = 0;
        }
    }

    printf("\n before print1DArray()\n");
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    print2DArray(a, 4,5);
    



    //메모리 해제
    for (i = 0; i < rows; i++)
    {
        free(a[i]); //각 행 해제
    }
    free(a);        // 포인터 배열 해제
    fclose(f);

    return 0;
}

void print2DArray(int** d, int rows, int cols)이 부분에 유의하자.

원하는 결과는 나왔으나, 좀더 간소화를 하자, n은 포인터 배열의 크기인 것 같다.

최종CI

#pragma warning(disable : 4996)
#include <stdio.h>
#include <stdlib.h>

void print2DArray(int **d, int rows, int cols)
{
    int i, j;
    int b[4] = {1, 3, 0, 2};

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

int main(void)
{
    FILE *f;
    if (fopen_s(&f, "f4.txt", "r") != 0)
    {
        printf("파일이 열리지 않습니다. \n");
        exit(1);
    }
    // 포인터 배열 선언
    int i = 0, rows = 4, cols = 5;
    int **a = (int **)malloc(rows * sizeof(int *));
    if (a == NULL)
    {
        fprintf(stderr, "Memory allocation failed for rows\n");
        return 1;
    }
    for (i = 0; i < rows; i++)
    {
        a[i] = (int *)malloc(cols * sizeof(int));
    }

    // 문자 체크

    int ch, currentNumber = 0;
    int j = 0, k = 0;
    while ((ch = fgetc(f)) != EOF)
    {
        if (isdigit(ch))
        {
            currentNumber = currentNumber * 10 + (ch - '0');
        }
        else if (ch == ' ')
        {
            a[j][k] = currentNumber;
            k++;
            currentNumber = 0;
        }
        else if (ch == '\n')
        {
            a[j][k] = currentNumber;
            j++;
            k = 0;
            currentNumber = 0;
        }
    }

    print2DArray(a, 4, 5);

    // 메모리 해제
    for (i = 0; i < rows; i++)
    {
        free(a[i]); // 각 행 해제
    }
    free(a); // 포인터 배열 해제
    fclose(f);

    return 0;
}

문제5

최종CI

#pragma warning(disable : 4996)
#include <stdio.h>
#include <stdlib.h>

int sumAry1D(int ary[], int size)
{
    int sum = 0;
    for (int i = 0; i < size; i++)
    {
        sum += ary[i];
    }
    return sum;
}

int main(void)
{
    FILE *file;
    int r, c;
    int **array;
    int totalSum = 0;

    // 파일열기
    file = fopen("f5.txt", "r");
    if (file == NULL)
    {
        perror("파일을 열 수 없습니다.");
        exit(EXIT_FAILURE);
    }

    // 배열의 크기 읽기
    fscanf(file, "%d %d", &r, &c);

    // 2차원 동적 배열 할당
    array = (int **)malloc(r * sizeof(int *));
    for (int i = 0; i < r; i++)
    {
        array[i] = (int *)malloc(c * sizeof(int));
    }

    // 배열의 데이터 읽기
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
        {
            fscanf(file, "%d", &array[i][j]);
        }
    }

    // 각 행의 합과 전체 합 계산
    for (int i = 0; i < r; i++)
    {
        int rowSum = sumAry1D(array[i], c);
        printf("%d\n", rowSum);
        totalSum += rowSum;
    }
    printf("%d\n", totalSum);

    // 동적 배열 해제
    for (int i = 0; i < r; i++)
    {
        free(array[i]);
    }
    free(array);

    // 파일 닫기
    fclose(file);

    return 0;
}

댓글남기기