본문 바로가기
PROGRAMMING/C

[POSTECH MOOC] 컴퓨터공학 입문Ⅱ - 4

by 안녕나는현서 2021. 4. 7.
728x90

본 내용은 POSTECH '청년 AI · Big Data 아카데미 온라인 기초과정'을 수강하며 정리한 내용입니다.

Ⅷ 배열과 구조체

 

<배열과 함수>

 

- 배열(array)

  • 동일한 자료형의 데이터가 여러 개 연속적으로 저장되어 있는 데이터 저장 장소
  • 많은 자료를 처리할 때, 여러 개를 한 번에 선언하고 각각의 데이터에 접근하여 처리할 수 있음
  • 자료형 배열이름 배열크기 -> int score[5];

- 배열의 초기화

  • 초기화
    • int score[5] = {90, 80, 70, 60, 50};
    • score[0] = 90, score[4] = 50
  • 배열의 크기 없이 초기화
    • int score[] = {90, 80, 70, 60, 50};
    • 자동적으로 초기값의 원소 개수만큼 배열 크기로 생성
  • 일부만 초기화
    • int score[5] = {90, 80};
    • score[0] = 90, score[1] = 80, score[2]~[4] = 0
    • 나머지 원소들은 0으로 초기화
  • 0으로 초기화
    • int score[5] = {0};
    • score[0]~[4] = 0

- 배열 선언과 메모리

  • int a[5] = {10, 20, 30, 40, 50};
  • 배열이 선언되면 배열명을 시작 주소로 연속된 메모리 공간(5개)이 만들어짐
  • 연속된 공간에 저장이 되어있으므로 원소명으로 원소(데이터)에 접근하거나 포인터(주소)를 사용하여 원소에 접근하여 값을 읽거나 변경 가능

  • 정수는 4바이트이므로 주소는 4씩 증가
  • a는 주소 상수이므로 변경 불가능
  • 배열 시작 주소 : a == &a[0]
  • a[1]원소의 주소 : a+1 == &a[1]
  • a[2] = 70; 또는 *(a+2) = 70; → a[2] 원소값이 70으로 변경

- 배열 예제 : 원소 값, 원소 주소값, 원소 합 출력

#include<stdio.h>

int main(void)
{
	int score[5] = {10, 20, 30, 40, 50,};
	int i, n, sum=0;
	
	/* 배열 원소의 수 : 배열의 바이트 수/integer의 바이트 수 */ 
	n = sizeof(score)/sizeof(int);
	
	/* 원소 값 출력 */ 
	printf("\n ** score 배열 ** \n");
	
	for (i=0; i<n; i++)
	{
		printf("score[%d] : %d \n", i, score[i]);
		
	}
	
	/* 원소 주소값 출력 */
	printf("\n ** score 배열주소 ** \n");
	
	for (i=0; i<n; i++)
	{
		printf("&score[%d] : %d \n", i, &score[i]);
	}
	
	/* 원소 합 출력 */	
	for (i=0; i<n; i++)
	{
		sum += score[i];
	}
	
	printf("\n 배열합 : %d \n", sum);
	
	return 0;
}

- 배열과 함수 예제 : main함수에 x배열, y배열을 선언하고 add_arrays함수를 만들어서 각각 원소를 더하는 연산 실행

#include <stdio.h>

void add_arrays(const int a[], const int b[], int absum[], int n);

int main(void)
{
	int x[5] = {10, 20, 30, 40, 50};
	int y[5] = {45, 55, 33, 28, 35};
	int xysum[5] = {0};
	int i, n;
	
	n = sizeof(x)/sizeof(int);
	
	printf("\n x배열 원소출력 :");
	for (i=0; i<n; i++)
	{
		printf("%d ", x[i]);
	}
	
	printf("\n\n y배열 원소출력 : ");
	for (i=0; i<n; i++)
	{
		printf("%d ", y[i]);
	}
	
	add_arrays(x, y, xysum, n);
	
	printf("\n\n x+y 결과 출력 : ");
	for (i=0; i<n; i++)
	{
		printf("%d ", xysum[i]);
	}
	return 0;
}
void add_arrays(const int a[], const int b[], int absum[], int n)
{
	int i;
	
	for (i=0; i<n; i++)
	{
		absum[i] = a[i] + b[i];
	}
}
  • const : 원본 배열의 값을 변경할 수 없도록 설정
  • 매개변수에서 배열형식[]으로 받아줄 경우, 포인터*를 쓰지 않아도 []연산자를 사용하여 원본의 배열을 직접 접근하여 읽거나 쓸 수 있는 기능을 제공함

 

<배열과 구조체>

 

- 기본 자료형

  • 프로그래밍 언어에서 기본적으로 제공하는 자료형
  • int, float, double, char 등

- 사용자 정의 자료형(User-defined data types)

  • 일상생활의 다양한 형태의 문제를 해결하기 위해서는 기본 자료형만으로 자료의 선언과 저장에 한계
  • 해결하려는 문제와 가장 가까운 자료구조를 사용자(프로그래머)가 직접 자료형으로 만들어서 문제 해결
  • 구조체 : struct

- 구조체

  • 배열의 경우에는 동일한 자료형의 데이터가 여러 개 필요한 경우에 사용
  • 성적 처리와 같이 학번, 점수, 학점 등 서로 다른 자료형을 가진 데이터를 함께 저장하고 처리하기 위해 사용
  • 다양한 자료형의 연관된 데이터를 묶어서 선언할 수 있도록 사용자 정의 자료형을 만드는 것
  • 템플릿과 같은 역할을 하며, 구조체의 정의는 메모리에 변수를 생성하지 않음
학생 성적 정보 구조체 정의
학번 : int ID
국어 : float kor
영어 : float eng
수학 : float math
평균 : float avg
학점 : char grade
struct stu
{
    int ID;
    float kor, eng, math, avg;
    char grade;
};
  • 구조체 정의를 main함수 위에 선언하면 전체 소스 코드에서 쓸 수 있고 함수 안에 선언하면 그 함수 내에서만 사용할 수 있음

- 구조체 변수 선언

  • 구조체 정의 후, 구조체 자료형을 사용하여 변수를 선언
  • 구조체 변수를 선언하면 구조체 멤버의 크기만큼 메모리에 할당
구조체 정의, 변수 선언 struct stu                                // 구조체 정의
{
    int ID;
    float kor, eng, math, avg;
    char grade;
};

struct stu s1                           // 구조체 변수 선언
타입 이름 변경 -> 구조체 변수가 너무 길 경우, typedef 함수를 이용해서 타입이름 변경 가능
typedef struct stu stu;
->
stu s1                                   // 구조체 변수 선언
구조체 변수 선언 struct stu s1 = {10001, 99.5, 88.7, 77.9};
struct stu s2;
. 연산자를 사용하여
구조체 멤버에 접근
s2.ID = 10001;
s2.kor = 90.5;
s2.eng = 80.3;
s2.math = 95.4;

 

- 구조체 배열 선언

  • 다른 배열과 같이 구조체 배열도 첨자를 이용하여 각 원소를 참조하며, 첨자는 0부터 (배열크기-1)까지 가능
구조체 정의 struct stu
{
    int ID;
    float kor, eng, math, avg;
    char grade;
};

구조체 배열 선언 struct stu s[3];

s[0].ID = 10001;
s[0].kor = 90.5;
s[0].eng = 80.3;
s[0].math = 95.4;
struct stu s[3] = {{1001, 85, 98, 89},
struct stu s[3] = {{1002, 77, 99, 88},
struct stu s[3] = {{1003, 97, 79, 89}};

 

- 구조체 배열 예제 : 성적처리

#include <stdio.h>
#define MAX 3 /* 소스코드 내에 MAX를 모두 3으로 바꿔줌 */

/* 구조체 정의 */ 
struct stu
{
	int ID;
	float kor, eng, math, avg;
	char grade;
};

int main(void) 
{
	/* 구조체 선언 */ 
	struct stu s[MAX];
	
	/* 변수 선언 */
	int i, j, korsum=0, engsum=0, mathsum=0;
	
	/* 학번, 점수 입력 */ 
	printf("학번, 점수(국어, 영어, 수학)를 입력하세요. \n");
	
	for (i=0; i<MAX; i++)
	{
		scanf("%d %f %f %f", &s[i].ID, &s[i].kor, &s[i].eng, &s[i].math);
	}
	
	/* 입력된 점수 출력하여 확인 */
	printf("\n 입력된 점수 \n");
	
	for (i=0; i<MAX; i++)
	{
		printf("%d %5.2f %5.2f %5.2f \n", s[i].ID, s[i].kor, s[i].eng, s[i].math);
	} 
	
	/* 평균 계산 */
	for (i=0; i<MAX; i++)
	{
		/* 학생별 평균 점수 */
		s[i].avg = (s[i].kor + s[i].eng + s[i].math)/3.0;
		
		/* 과목 총점 계산 */
		korsum += s[i].kor; 
		engsum += s[i].eng; 
		mathsum += s[i].math; 
	 } 
	 
	/* 학점 계산 */
	for (i=0; i<MAX; i++)
	{
		if (s[i].avg>=90)
			s[i].grade = 'A';
		else if (s[i].avg>=80)
			s[i].grade = 'B';
		else if (s[i].avg>=70)
			s[i].grade = 'C';
		else if (s[i].avg>=60)
			s[i].grade = 'D';
		else
			s[i].grade = 'F';
	 } 
	 
	/* 학번, 평균, 학점 출력 */
	printf("\n ** 성적 ** \n");
	
	for(i=0; i<MAX; i++)
	{
		printf("학번 : %5d \t 평균 :  %5.2f \t 학점 : %c \n", s[i].ID, s[i].avg, s[i].grade);
	}
	
	/* 과목별 평균 출력 */
	printf("\n ** 과목별 평균 ** \n");
	printf("국어 : %5.2f \t 영어 : %5.2f \t 수학 : %5.2f \n", korsum/3.0, engsum/3.0, mathsum/3.0);
	
	return 0; 
}

728x90

댓글