11 분 소요

01)구조체와 공용체

구조체 정의와 구조체 변수 선언

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

//은행계좌정보를 위한 구조체
struct account
{
	char name[12];
	int actnum;
	double balance;
};

int main() {
	//구조체 변수 선언 및 초기화
	//1.mine이라는 이름을 구조체 정의하고 info 삽입, mine이 소유
	struct account mine = {"홍길동", 1001, 300000};

	//2.yours이라는 이름을 구조체 정의하고 info 삽입, yours가 소유
	struct account yours;

	strcpy(yours.name, "이동원");

	yours.actnum = 1002;
	yours.balance = 500000;

	//구조체의 멤버들 출력
	printf("구조체 크기: %zu\n", sizeof(mine));
	printf("%s %d %.2f\n", mine.name, mine.actnum, mine.balance);
	printf("%s %d %.2f\n", yours.name, yours.actnum, yours.balance);

	return 0;
}

구조체는 일반변수의 상위호환버전이다. 따라서 일반변수가 할수있는 일들이 구조체가 모두 수행할 수 있다.

함수에서 값을 반환할때 한개만 반환할수있다고 생각했는데, 찾아보니, 구조체를 반환하는 꼴이면 여러개의 값도 전달하는게 가능할 것이다.

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

//은행계좌정보를 위한 구조체
struct account
{
	char name[12];
	int actnum;
	double balance;
};

//계좌 정보를 반환하는 함수
struct account getAccount()
{
	struct account acc;
	//사용자로부터 정보 입력 받기
	printf("이름으 입력하세요 (최대 11자 이내): ");
	scanf("%s", acc.name);

	printf("계좌 번호를 입력하세요: ");
	scanf("%d", &acc.actnum);

	printf("잔액을 입력하세요: ");
	scanf("%lf", &acc.balance);

	return acc;
}

int main() {
	//계좌정보를 저장할 변수
	struct account myAccount;

	//계좌 정보 입력 받기
	myAccount = getAccount();

	//입력받은 계좌 정보 출력
	printf("\n입력받은 계좌정보:\n");
	printf("이름: %s\n", myAccount.name);
	printf("계좌번호: %d\n", myAccount.actnum);
	printf("잔액: %.2lf\n", myAccount.balance);

	return 0;
}

구조체간의 의존 및 상속은 가능하다.

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

// 날짜 구조체
struct date
{
	int year;
	int month;
	int day;
};

//은행계좌정보 구조체
struct account
{
	struct date dates;  //계좌 개설일자 -> 구조체간의 의존 및 상속은 가능하다.
	char name[12];
	int actnum;
	double balance;
};

int main() {
	//계좌정보를 저장할 변수
	struct account myAccount = { {2022,3,9}, "윤성웅", 1001, 300000 };



	//입력받은 계좌 정보 출력
	printf("\n<입력받은 계좌정보>\n");
	printf("개설일자: [%d. %d. %d]\n", myAccount.dates.year, myAccount.dates.month, myAccount.dates.day );
	printf("이름: %s\n", myAccount.name);
	printf("계좌번호: %d\n", myAccount.actnum);
	printf("잔액: %.2lf\n", myAccount.balance);

	return 0;
}

CI: 계좌정보 입력하고 조회하기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <windows.h> //오늘 날짜 받아오기

//날짜 구조체
struct date
{
	int year;
	int month;
	int day;
};

//은행계좌정보 구조체
struct account
{
	struct date date; //개설일자 -> 구조체 간의 의존 및 상속 가능
	char name[12];
	long actnum;
	double balance;
};

//오늘 날짜 정보를 반환하는 함수
void getCurrentDate(int* year, int* month, int* day)
{
	SYSTEMTIME systemTime;
	GetLocalTime(&systemTime);

	*year = systemTime.wYear;
	*month = systemTime.wMonth;
	*day = systemTime.wDay;
}

//계좌정보를 반환하는 함수 -> 마치 (클래스의)생성자처럼 볼수가 있겠다
struct account putAccount()
{
	struct account acc;
	//사용자로부터 정보 입력 받기
	printf("이름을 입력하세요 (최대 11자 이내): ");
	scanf("%s", acc.name);

	printf("계좌 번호를 입력하세요: ");
	scanf("%d", &acc.actnum);

	printf("잔액을 입력하세요: ");
	scanf("%lf", &acc.balance);
	
	//개설날짜 저장
	SYSTEMTIME systemTime;
	GetLocalTime(&systemTime);
	acc.date.year = systemTime.wYear;
	acc.date.month = systemTime.wMonth;
	acc.date.day = systemTime.wDay;

	return acc;
}
void getAccount(struct account account)
{
	//입력받은 계좌 정보 출력
	printf("\n입력받은 계좌정보:\n");
	printf("이름: %s\n", account.name);
	printf("개설일자: [%d.%d.%d]\n",
		account.date.year, account.date.month, account.date.day);
	printf("계좌번호: %d\n", account.actnum);
	printf("잔액: %.2lf\n", account.balance);
}

int main() {
	//계좌정보를 저장할 변수
	struct account myAccount;

	//계좌 정보 입력 받기
	myAccount = putAccount();
	getAccount(myAccount);

	return 0;
}

output>

이름을 입력하세요 (최대 11자 이내): 윤성웅 계좌 번호를 입력하세요: 942902 잔액을 입력하세요: 15000

입력받은 계좌정보: 이름: 윤성웅 개설일자: [2024.1.12] 계좌번호: 942902 잔액: 15000.00

시험출제내용: char 포인터와 char 배열의 비교

image-20240112094724767

전자는 포인터를 선언할 뿐이다. 어떤 메모리도 할당되지않은상태이다. 따라서 strcpy()로 구현하려면 또는 scanf()로 구현하려면 해당 문자열을 메모리(RAM)의 어떤 공간에 일단 저장하고, 바로 dept포인터가 거기를 참조하게 두어야 한다.=> strcpy(*dept, "컴퓨터정보공학과") , scanf("%s", *dept)

공용체의 멤버 접근

자료형에 대한 예시

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

typedef enum {
	INT, 
	FLOAT, 
	CHAR
} DataType;

typedef union {
	int i;
	float f;
	char c;
} Data;

typedef struct {
	DataType type;
	Data data;
} TypeData;

void printData(TypeData d) {
	switch (d.type) {
	case INT:
		printf("Integer: %d\n", d.data.i);
		break;
	case FLOAT:
		printf("Float: %f\n", d.data.f);
		break;
	case CHAR:
		printf("Char: %c\n", d.data.c);
		break;
	}
}

int main() {
	TypeData data;
	data.type = INT;
	data.data.i = 5;
	printData(data);

	data.type = FLOAT;
	data.data.f = 3.14;
	printData(data);

	data.type = CHAR;
	data.data.c = 'a';
	printData(data);

	return 0;
}

사람info에 대한 예시

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

typedef struct {
	char street[50];
	char city[50];
	char state[3];
	int zip;
} Address;

typedef struct {
	char name[50];
	int age;
	Address address;
}Person;

void printPersonInfo(Person p) {
	printf("Name: %s\n", p.name);
	printf("Age: %d\n", p.age);
	printf("Address: %s, %s, %s, %d\n",
		p.address.street,
		p.address.city,
		p.address.state,
		p.address.zip);
}

int main() {
	Person person = {
		"John Doe",
		30,
		{"123 Main St", "Anytown", "NY", 12345}
	};

	printPersonInfo(person);

	return 0;
}

공용체 필드에서 가장 큰 데이터 타입으로 해당 공용체의 크기가 할당된다. (다 더해야 하는거 아닌가?ㄷㄷ?)

라고 생각할수있는데 이는 구조체와 공용체의 차이를 제대로 구분짓지 못해서 발생한 문제이다.

구조체는 위 말대로 그 안에 멤버들의 사이즈 총합으로 할당이 되어야 한다. 경우에 따라서 멤버들을 모두 사용하게 될수도 있기 때문이다.

하지만 공용체는 그 안에 있는 것 중 무조건 하나만 끌어와서 사용한다. 그래서 그 안에 1바이트 자료형, 4바이트 자료형, 8바이트 자료형이 명시되어 있을때,

이중 하나밖에 사용하지 못한다. 만약 선언된 한개의 공용체에 모든 멤버에 접근할 수가 있다라면 이는 곧 구조체가 아니더냐?

하지만 공용체는 오로지 한개밖에 사용할수가 없다!

이렇게 구조체와 공용체의 차이에 대해 정리해보았다.

image-20240112100308985

image-20240112100326332

02)자료형 재정의

문장 typedef를 이용하여 구조체 자료형을 다른 이름으로 재정의해 사용

예시(1) 제품정보을 구조체로 넣어보기

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

struct date
{
	int year;
	int month;
	int day;
};

typedef struct date date;


int main() {
	//구조체를 정의하면서 바로 자료형 software로 정의하기 위한 구문
	typedef struct
	{
		char title[30];		//제목
		char company[30];	//제직회사
		char kinds[30];		//종류
		date release;		//출시일
	}software;

	software vs = { "비주얼스튜디오 커뮤니티", "MS", "통합개발환경",
		{2022, 8, 29} };

	printf("제품명: %s\n", vs.title);
	printf("회사  : %s\n", vs.company);
	printf("종류  : %s\n", vs.kinds);
	printf("출시일: %d. %d. %d\n", vs.release.year, vs.release.month, vs.release.day);


	return 0;
}

예시(2) 학생정보를 구조체로 넣어보기

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

typedef struct {
	char name[50];
	int age;
	float grade;
} Student;

void inputStudent(Student* s) {
	printf("Enter student's name: ");
	gets(s->name);

	printf("Enter student's age: ");
	scanf("%d", &s->age);

	printf("Enter student's grade: ");
	scanf("%f", &s->grade);
}

void printStudent(const Student* s) {
	printf("Name: %s, Age: %d, Grade: %.2f\n", s->name, s->age, s->grade);
}

int main() {
	Student student;

	printf("Enter student information> \n");
	inputStudent(&student);

	printf("\nStudent Information>\n");
	printStudent(&student);

	return 0;
}

여기서는 구조체 포인터를 이용해서 값을 넘겨받아 사용했다.(사실 이게 더 많이 쓰는 방식이다.)

동적할당 : 구조체

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

typedef struct {
	char name[50];
	int age;
	float grade;
} Student;

void inputStudent(Student* s) {
	printf("학생 이름을 입력하세요: ");
	gets(s->name);  // gets 함수는 보안 상 문제가 있으므로 권장되지 않습니다. 추후 수정이 필요합니다.

	printf("학생 나이를 입력하세요: ");
	scanf("%d", &s->age);

	printf("학생 성적을 입력하세요: ");
	scanf("%f", &s->grade);
}


void printStudent(const Student* s) {
	printf("이름: %s, 나이: %d, 성적: %.2f\n", s->name, s->age, s->grade);
}

int main() {
	Student* student = (Student*)malloc(sizeof(Student));

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


	printf("Enter student information> \n");
	inputStudent(student);

	printf("\nStudent Information>\n");
	printStudent(student);

	free(student);

	return 0;
}

CI: 계좌정보 입력하고 조회하기(구조체 포인터 이용)

03)구조체와 공용체의 포인터와 배열

구조체 포인터의 선언과 사용

공용체는 필드(멤버)가 여러개라도 선언후 하나만 저장이 가능한데, 이는 구조체와의 차이점이다. 데이터 타입이 달라서 쓰는거다. 메모리를 다른 변수간에 공유한다

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

struct lecture
{
	char name[20];
	int type;
	int credit;
	int hours;
};

typedef struct lecture lecture;

//제목을 위한 문자열
char* head[] = {"강좌명", "강좌구분", "학점", "시수"};
//강조 종류를 위한 문장열
char* lectype[] = { "교양", "일반선택", "전공필수", "전공선택" };

int main() {
	lecture os = { "운영체제", 2, 3, 3 };
	lecture c = { "C프로그래밍", 3, 3, 4 };
	lecture* p = &os;

	printf("구조체 크기: %zu, 포인터 크기: %zu\n\n", sizeof(os), sizeof(p));
	printf("%10s %12s %6s %6w\n", head[0], head[1], head[2], head[3]);
	printf("%12s %10s %5d %5d\n", p->name, lectype[p->type], p->credit, p->hours);

	//포인터 변경
	p = &c;
	printf("%12s %10s %5d %5d\n", (*p).name, lectype[(*p).type], (*p).credit, (*p).hours);
	printf("%12c %10s %5d %5d\n", *c.name, lectype[c.type], c.credit, c.hours);


	return 0;
}

구조체 배열을 선언한 후 내용출력

예시(1)

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

struct lecture
{
	char name[20];
	int type;
	int credit;
	int hours;
};

typedef struct lecture lecture;

char* lectype[] = { "교양", "일반선택", "전공필수", "전공선택" };
char* head[] = {"강좌명", "강좌구분", "학점", "시수"};

int main() {
	//구조체 lecture의 배열선언 및 초기화
	lecture course[] = {
		{"인간과 사회", 0, 2, 2},
		{"경제학개론",1, 3, 3},
		{"자료구조",2, 3 ,3},
		{"모바일프로그래밍",2, 3, 4},
		{"고급 C프로그래밍",3, 3, 4}
	};

	int arysize = sizeof(course) / sizeof(course[0]);


	printf("배열크기: %d\n\n", arysize);
	printf("%12s   %12s %6s %6s\n", head[0], head[1], head[2], head[3]);
	printf("=================================================\n");

	for (int i = 0; i < arysize; i++)
	{
		printf("%16s %10s %5d %5d\n", course[i].name,
		lectype[course[i].type], course[i].credit, course[i].hours);
	}
	return 0;
}

구조체 배열 : 동적할당

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

typedef struct {
    int id;
    char name[100];
    float score;
} Student;

int main() {
    Student* students;
    int n, i;

    printf("학생 수를 입력하세요: ");
    scanf("%d", &n);

    students = (Student*)malloc(n * sizeof(Student));
    if (students == NULL) {
        fprintf(stderr, "메모리 할당 실패\n");
        return 1;
    }

    for (i = 0; i < n; i++) {
        printf("학생 %d의 ID: ", i + 1);
        scanf("%d", &students[i].id);

        printf("학생 %d의 이름을 입력하세요: ", i + 1);
        scanf("%s", students[i].name); // 배열에 대한 주소 전달이므로 &를 사용하지 않습니다.

        printf("학생 %d의 점수: ", i + 1);
        scanf("%f", &students[i].score);
    }

    printf("\n--- 학생 목록 ---\n");
    for (i = 0; i < n; i++) {
        printf("ID: %d, 이름: %s, 점수: %.2f\n",
            students[i].id,
            students[i].name,
            students[i].score
        );
    }

    free(students);
    return 0;
}

위코드에서 scanf("%s", students[i].name);가 작동하지 않는 문제가 발생함.

->알고보니 그 이전 scanf()에서 내가 이상한 값을 넣었다. 형식지정자가 %d라서 정수형만 넣을수가 있는데 내가 abc라는 문자열 넣어버리는 바람에 그 뒤 순서에서도 입력 버퍼 라던가 그런 곳에서 꼬인 것 같다.

실습문제

1번)

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

typedef struct {
    char title[100];
    char director[100];
    int year;
    int runningTime;
} MovieData;

void getMovieData(const MovieData* moviedata) {
    printf("Title: %s\n", moviedata->title);
    printf("Director: %s\n", moviedata->director);
    printf("Year: %d\n", moviedata->year);
    printf("Running Time: %d\n", moviedata->runningTime);
}

int main(void) {
    int n, i;

    printf("Enter the number of movies: ");
    scanf("%d", &n);

    MovieData* moviedata = (MovieData*)malloc(n * sizeof(MovieData));

    if (!moviedata) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }

    for (i = 0; i < n; ++i) {
        printf("Movie %d:\n", i + 1);

        printf("Title: ");
        scanf("%s", moviedata[i].title);

        printf("Director: ");
        scanf("%s", moviedata[i].director);

        printf("Year: ");
        scanf("%d", &moviedata[i].year);

        printf("Running Time: ");
        scanf("%d", &moviedata[i].runningTime);
    }

    for (i = 0; i < n; ++i) {
        printf("\nMovie %d:\n", i + 1);
        getMovieData(&moviedata[i]);
    }

    free(moviedata);

    return 0;
} //이슈를 해결하지 못함

한가지 인사이트>

typedef struct {...} MovieDatastruct MovieData{...}는 아예 다르다.

아래 코드에서는 전자의 구문을 사용해서는 안된다.

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

typedef struct {
    char title[100];
    char director[100];
    int year;
    int runningTime;
} MovieData;

void getMovieData(const MovieData* moviedata) {
    printf("Title: %s\n", moviedata->title);
    printf("Director: %s\n", moviedata->director);
    printf("Year: %d\n", moviedata->year);
    printf("Running Time: %d\n", moviedata->runningTime);
}

int main(void) {
    // MovieData 구조체 변수 동적 할당
    struct MovieData* movie = (struct MovieData*)malloc(sizeof(struct MovieData));

    // 사용자로부터 정보 입력 받기
    printf("Enter the title: ");
    fgets(movie->title, sizeof(movie->title), stdin);

    printf("Enter the director: ");
    fgets(movie->director, sizeof(movie->director), stdin);

    printf("Enter the year: ");
    scanf("%d", &movie->year);

    printf("Enter the running time: ");
    scanf("%d", &movie->runningTime);

    // 입력 받은 정보 출력
    printMovieData(movie);

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

    return 0;
}

E0070: 불완전한 형식을 사용할 수 없습니다.

E0393: 불완전한 클래식 형식 “struct MovieData”에 대한 포인터는 사용할 수 없음.

최종CI

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

// MovieData 구조체 정의
struct MovieData {
    char title[100];
    char director[100];
    int year;
    int runningTime;
};

// 출력 함수 정의
void printMovieData(struct MovieData* movie) {
    printf("Title : %s", movie->title);
    printf("Director : %s", movie->director);
    printf("Year : %d\n", movie->year);
    printf("RunningTime : %d\n", movie->runningTime);
}

int main(void) {
    // MovieData 구조체 변수 동적 할당
    struct MovieData* movie = (struct MovieData*)malloc(sizeof(struct MovieData));

    // 사용자로부터 정보 입력 받기
    printf("Enter the title: ");
    fgets(movie->title, sizeof(movie->title), stdin);

    printf("Enter the director: ");
    fgets(movie->director, sizeof(movie->director), stdin);

    printf("Enter the year: ");
    scanf("%d", &movie->year);

    printf("Enter the running time: ");
    scanf("%d", &movie->runningTime);

    // 입력 받은 정보 출력
    printMovieData(movie);

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

    return 0;
}

2번

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct employee {
	int emp_id;
	char name[50];
	char address[100];
	double salary;
	double incentive;
};

void printEmployee(struct employee emp) {
	double annual_salary = emp.salary * (12 + emp.incentive);

	printf("%d %s %s %.01f %.01f%% %.1lf\n",
		emp.emp_id, emp.name, emp.address, emp.salary, emp.incentive * 100, annual_salary);
}

int main() {
	// 배열을 사용하여 데이터 입력
	struct employee employees[3];

	FILE* file = fopen("f2.txt", "r");
	if (file == NULL) {
		printf("파일을 열 수 없습니다.\n");
		return 1;
	}

	for (int i = 0; i < 3; i++) {
		fscanf(file, "%d", &employees[i].emp_id);
		fscanf(file, "%s", employees[i].name);
		fscanf(file, " %[^\n]", employees[i].address);
		fscanf(file, "%lf", &employees[i].salary);
		fscanf(file, "%lf", &employees[i].incentive);
	}

	fclose(file);

	// 데이터 출력
	for (int i = 0; i < 3; i++) {
		printEmployee(employees[i]);
	}

	return 0;
}

여기서 주목할 것은 scanf()이다. 문자를 읽어내냐, 숫자를 읽어내냐에 따라 직접주소연산자가 붙을수도 있고, 안붙을수도 있기 때문이다. 또한 아래 31,32번 라인을 보면,

fscanf(file, "%s", employees[i].name);
fscanf(file, " %[^\n]", employees[i].address);

31번 라인에서는 직접주소연산자를 쓰지 않았고, 32번도 마찬가지로 직접주소연산자를 쓰지 않았다.

그리고 32번 라인에서는 공백을 하나 넣어주었다.

1.fscanf(file, "%s", employees[i].name);:
  • employees[i].name은 문자열을 담고 있는 배열입니다. 배열의 이름 자체가 배열의 시작 주소를 나타내기 때문에 추가적으로 &연산자를 사용하지 않아도 됩니다.
2.fscanf(file, " %[^\n]", employees[i].address);:
  • ` %[^\n] 형식지정자는 개행문자(\n`)가 아닌 모든 문자를 입력받습니다.
  • scanf함수 계열에서는 %s형식 지정자가 공백을 기준으로 문자열을 읽기 떄문에, fscanf에서 %[^\n]을 사용하여 개행문자를 제외한 모든 문자를 읽어옵니다.
  • 앞에 공백이 있는 이유는, 이전에 남아있을 수 있는 개행 문자를 무시하고 다음 문자열을 읽기 위함입니다. 이를 통해 이전에 입력받은 엔터 키 등의 공백문자를 무시하고 새로운 문자열을 받을 수 있습니다.

3번

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

typedef struct
{
    double x;
    double y;
} point;

typedef struct
{
    double slope;
    double yintercept;
} line;

line calculateLine(point A, point B)
{
    line result;
    result.slope = (B.y - A.y) / (B.x - A.x);
    result.yintercept = A.y - result.slope * A.x;
    return result;
}

int main()
{
    point A, B;
    line result;

    scanf("%lf %lf", &A.x, &A.y);
    scanf("%lf %lf", &B.x, &B.y);

    result = calculateLine(A, B);
    printf("%.1lf %.1lf\n", result.slope, result.yintercept);
    return 0;
}

4번

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct
{
    char fname[100];
    int calories;
} Food;

int totalCalories(Food ary[], int size)
{
    int total = 0;
    for (int i = 0; i < size; i++)
    {
        total += ary[i].calories;
    }
    return total;
}

int main()
{
    FILE *file = fopen("f4.txt", "r");
    if (!file)
    {
        fprintf(stderr, "파일을 열수 없습니다.");
        return 1;
    }

    // 구조체 배열에 데이터 입력받기
    const max_entries = 100; // 최대 음식 수
    Food foodArray[100];
    int count = 0; // 실제로 읽은 음식 수

    while (fscanf(file, "%s %d", foodArray[count].fname, &foodArray[count].calories) == 2)
    {
        count++;
        if (count >= max_entries)
        {
            fprintf(stderr, "음식 수가 너무 많습니다. 더 많은 공간을 할당해야 합니다.\n");
            return 1;
        }
    }
    // 파일 닫기
    fclose(file);

    // 전체 칼로리 계산 및 출력
    int total = totalCalories(foodArray, count);
    printf("%d\n", total);
    return 0;
}

5번

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

// 구조체 정의
struct Student {
    int number;
    char name[50];
    float score1, score2, quiz;
    float totalScore; // 추가: 성적의 합계를 저장할 필드
};

// 함수 선언
void readDataFromFile(struct Student** students, int* n);
void calculateTotalScore(struct Student* students, int n);
void printData(struct Student* students, int n);
void searchByName(struct Student* students, int n, char* searchName);

int main() {
    struct Student* students;
    int n;
    char searchName[50];

    // 파일에서 데이터 읽기
    readDataFromFile(&students, &n);

    // 성적의 합계 계산
    calculateTotalScore(students, n);

    // 데이터 출력
    printData(students, n);

    // 검색할 이름 입력
    printf("\nEnter the name to search: ");
    scanf("%s", searchName);

    // 이름으로 검색 및 결과 출력
    searchByName(students, n, searchName);

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

    return 0;
}

// 파일에서 데이터 읽기
void readDataFromFile(struct Student** students, int* n) {
    FILE* file = fopen("f5.txt", "r");
    if (!file) {
        printf("Error opening file.\n");
        exit(1);
    }

    // 데이터 개수 읽기
    fscanf(file, "%d", n);

    // 동적할당을 통해 구조체 배열 생성
    *students = (struct Student*)malloc(*n * sizeof(struct Student));

    // 데이터 읽기
    for (int i = 0; i < *n; i++) {
        (*students)[i].number = i + 1; // 번호는 배열의 인덱스 + 1로 설정
        fscanf(file, "%s %f %f %f", (*students)[i].name, &(*students)[i].score1, &(*students)[i].score2, &(*students)[i].quiz);
    }

    fclose(file);
}

// 성적의 합계 계산
void calculateTotalScore(struct Student* students, int n) {
    for (int i = 0; i < n; i++) {
        students[i].totalScore = students[i].score1 + students[i].score2 + students[i].quiz;
    }
}

// 데이터 출력
void printData(struct Student* students, int n) {
    printf("\nData:\n");
    for (int i = 0; i < n; i++) {
        printf("%d %s %.1f %.1f %.1f %.1f\n", students[i].number, students[i].name, students[i].score1, students[i].score2, students[i].quiz, students[i].totalScore);
    }
}

// 이름으로 검색 및 결과 출력
void searchByName(struct Student* students, int n, char* searchName) {
    for (int i = 0; i < n; i++) {
        if (strcmp(students[i].name, searchName) == 0) {
            printf("\nSearch Result:\n");
            printf("%d %s %.1f %.1f %.1f %.1f\n", students[i].number, students[i].name, students[i].score1, students[i].score2, students[i].quiz, students[i].totalScore);
            return; // 검색 결과를 찾았으면 함수 종료
        }
    }

    // 검색 결과를 찾지 못한 경우
    printf("\nSearch Result:\n");
    printf("Name not found.\n");
}

enum써서 요일 출력하기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

enum days {SUN, MON, TUE, WED, THU, FRI, SAT};

char* days_name[] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};

int main() {
    for (enum days currentDay = SUN; currentDay <= SAT; currentDay++) {
        printf("%s\n",days_name[currentDay]);
    }
    return 0;
}

days라는 열거형은 0부터 6까지의 값을 갖는 7개의 변수가 있다. 근데 나는 키워드라 부르는게 더 이해가 잘 된다.

아무래도 일반적인 변수들과는 달리 값이 순서에 따라 절대적으로 정해지기 때문이다.

키워드를 순차적으로 돌려서 그 키워드에 맞는 값이 days_name[]이라는 문자열 배열에 순차적으로 들어가면서 포인터배열에서 각각의 포인터를 돌려가면서 가리키고, 가리킨 포인터는 또다시 문자열을 가리키게 된다.

댓글남기기