C언어 기초 (5) : 배열

STUDY_J·2024년 7월 3일

기초지식

  • main 함수에서 main(void){ }를 쓰는 이유
    - int main(void)를 사용하는 것이 더 명확하고 권장됨. 이는 함수가 인자를 받지 않음을 명확히 나타내며, 코드의 가독성을 높여줌
    - int main()는 인자가 명시되지 않은 상태를 의미하며, 컴파일러에 따라 다르게 해석될 수 있음. 따라서 현대 C에서는 잘 사용되지 않음.
  • return 0; 을 써주는 이유
    - 명확한 종료 상태
    return 0;은 프로그램이 정상적으로 종료되었음을 운영체제에 알려줍니다.
    C 표준에서는 main 함수의 끝에 도달했을 때 암묵적으로 return 0;이 추가되는 것으로 간주함.
    그러나 명시적으로 return 0;을 추가하면 프로그램의 종료 상태가 명확히 표현됨.

배열

  • 지하철 칸마다 사람이 몇 명 타있는지 출력해보기
#include <stdio.h>

int main()
{
	int subway1 = 30;
	int subway2 = 40;
	int subway3 = 50;
	
	printf("%d people are in subway 1\n",subway1);
	printf("%d people are in subway 2\n",subway2);
	printf("%d people are in subway 3\n",subway3);
	
	return 0;
}

위의 코드에서는 각 지하철 칸 별로, 사람의 수를 정의해주고 있다.
이는 칸이 많아질수록 번거로운 작업이 되므로 이때 "배열"이 필요하다.

#include <stdio.h>

int main()
{
	int subway_array[3]; // 0~2
	subway_array[0] = 30;
	subway_array[1] = 40;
	subway_array[2] = 50;
	
	for(int i = 0; i<3; i++)
	{
		printf("%d people are in subway %d\n", subway_array[i], i+1);
	}
	
	return 0;
}

  • for 문과 배열을 사용하기
#include <stdio.h>

int main()
{
	int arr[10]  = {1,2,3,4,5,6,7,8,9,10};
	for(int i = 0; i < 10; i++){
		printf("%d\n",arr[i]);
	}
	return 0;
}

위에서 int arr[10]을 선언만 해주고 초기화를 해주지 않으면 ( ex. int arr[10]; ) 이상한 값(dummy)을 출력하게 된다.
그래서 항상 값은 초기화를 해주어야 한다.

또한 배열 크기는 항상 상수로 선언을 해주어야 한다

  • 잘못된 예시
int size = 10;
int arr[size];
// 위의 코드는 잘못된 예시임

int arr[10] = ...; // 이와 같이 작성해야함.

  • 배열의 크기 선언시에 배열의 크기와 맞지 않게 선언을 한다면 자동으로 '0'으로 출력된다.
    (크기를 아예 선언해주지 않으면 쓰레기 값으로 출력됨)
#include <stdio.h>

int main()
{
	int arr[10] = {1,2};
	for(int i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	
	return 0;
}
int arr[] = {1,2}; //를 사용해도 괜찮다.
//자동적으로 int arr[2] 로 인식한다.

  • float 출력
#include <stdio.h>

int main()
{
	float arr[10] = {1.0f,2.0f, 3.0f};
	for(int i = 0; i < 10; i++)
	{
		printf("%.2f\n", arr[i]); // .2 는 소수점 둘째 자리까지 출력
	}
	
	return 0;
}

문자, 문자열을 사용한 배열

#include <stdio.h>

int main(void)
{
	char c = 'A'; // 문자 
	printf("%c\n",c);
    
    char str[6] = "coding"; // [c][o][d][i][n][g]
	printf("%s\n", str);
	
	return 0;
}
  • 문자열 출력시 주의할 점 !!
    문자열 끝에는 "끝"을 의미하는 NULL 문자 '\0'이 포함되어야 한다.
    따라서 char[6] = "coding"; 이 아닌
    char[7] = "coding"; 으로 작성하여 한 칸의 여유를 주어야 한다.

다음과 같이 작성해도 괜찮다.

#include <stdio.h>

int main(void)
{
	char str2[] = "coding";
	printf("%s\n", str2);
	printf("%lu\n", sizeof(str2));
	
	return 0;
}
  • for문을 사용하여 문자 출력하기
#include <stdio.h>

int main(void)
{
	char c = 'A';
	printf("%c\n",c);
	
	char str[7] = "coding"; // [c][o][d][i][n][g]
	printf("%s\n", str);
	
	char str2[] = "coding";
	//printf("%s\n", str2);
	//printf("%lu\n", sizeof(str2));
	
	for(int i = 0; i<sizeof(str2); i++)
	{
		printf("%c\n", str2[i]);
	}
	
	return 0;
}

  • 문자열 출력
#include <stdio.h>

int main(void)
{
	char c_array[10] = {'c', 'o', 'd','i','n','g'};
	printf("%s\n", c_array);
	
	for(int i = 0; i<sizeof(c_array); i++)
	{
		printf("%c\n", c_array[i]);
	}
	return 0;
}

아스키코드란?

  • ASCII 코드는 미국 표준협회에서 제시한 표준 코드 체계이다.
    7bit, 총 128개 코드(0~127)
    -예시
    a : 97 (문자 a의 아스키 코드)
    A : 65
    0 : 48
#include <stdio.h>

int main(void)
{
	char name[256];
	printf("Put yout name : ");
	scanf("%s", name);
	printf("%s\n", name);

	return 0;
}

  • 이름을 입력하고, 문자열의 끝인 '\0'을 만나면 종료되도록 설정한 후, scanf에 입력된 문자의 아스키 코드를 출력하도록 코드를 작성함
#include <stdio.h>

int main(void)
{
	char name[256];
	printf("Put yout name : ");
	scanf("%s", name);
	printf("%s\n", name);
	
	for(int i = 0; i<sizeof(name); i++)
	{
		if(name[i] == '\0')
		{
			break;
		}
		printf("%d\n", name[i]);
	}
	return 0;
}

프로젝트

  • 발모제를 맞추는 게임
    4개의 화학물을 n 번의 조합으로 뿌렸을 때, 몇 번째 화학물이 발모제인지 맞추는 게임

  • 직접 작성한 코드

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


int main(void)
{
	srand(time(NULL)); //코드 실행시 난수가 바뀌게 설정해주기 위함
	int potion = rand() %4; // 실제 발모제 순서
	printf("\n\n-----Game start!-----\n\n");
	
	
	//3번의 기회
	for(int i = 1; i <=3; i++)
	{
		int bottle[] = {0, 0, 0, 0};
		int thisgame = rand() %2+2; // 0~1 -> 2~3, 2개 혹은 3개를 랜덤으로 고를거임
		printf("\n%d번째 게임을 진행중입니다.\n", i);
		int chosen = 0;
		
		for(int j = 1; j<=thisgame; j++) // 병의 배열에서 선택된 병을 표시하는 작업을 할거임
		{
			int choice = rand() %4; // 2개 혹은 3개를 고를건데, 몇 번째 병이 골라지는지 설정 
			
			// 만약 n번째 병을 골랐는데 그 값이 0이라면 1로 변경해줘야 참여자에게 보여줄 수 있음
			if(bottle[choice] == 0)
			{
				bottle[choice] = 1;
				
				//선택된 병이 발모제라면 그 내용을 참여자에게 알려줘야 함
				if(choice == potion)
				{
					chosen = 1;
				}
			}
			
		}
		
		// 병의 배열에서 1로 바뀐 부분이 있으면 그 내용을 참여자에게 알려주어야 함
		for(int k = 0; k<4 ; k++)
		{
			if(bottle[k] == 1)
			{
				printf("%d ", k+1);
			}
		}
		
		printf("\n\n발모제를 바르겠습니다\n\n");
		
		if(chosen == 1)
		{
			printf("-----이 중에 발모제가 존재합니다-----\n");
		}
		else
		{
			printf("-----발모제는 없습니다-----\n");
		}
	
	}
	
	printf("\n발모제는 몇 번째 병에 존재합니까? ");
	int answer;
	scanf("%d", &answer);
	
	if(answer == potion+1)
	{
		printf("정답입니다\n");
	}
	else
	{
		printf("오답입니다\n");
	}

	return 0;
}
  • 여기서 주의할 점 : 마지막에 정답과 입력값을 비교할 때, 기존의 정답은 0~3 범위이므로 마지막에 1을 더한 후에 비교해야한다. 입력자는 1번째부터 4번째 병이라고 인지하기 때문임.

  • 강의 내용에서의 코드
    출처 : 나도코딩 (https://www.youtube.com/watch?v=q6fPjQAzll8&t=8003s)

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

int main(void) 
{
    srand(time(NULL)); // 경고를 없애려면 srand((unsigned int)time(NULL)); 
    int treatment = rand() % 4; // 진짜 발모제 선택(0~3)
    printf("\n\n === 자라나라 머리카락 게임 === \n\n");

    int cntShowBottle = 0; // 이번 회차에 조합할 약병 개수
    int prevCntShowBottle = 0; // 앞 회차에서 조합한 약병 개수

    // 3번 테스트
    for (int i = 1; i <= 3; i++) 
    {
        int bottle[4] = { 0, 0, 0, 0 }; // 약병 4개
        do {
            cntShowBottle = rand() % 2 + 2; // 조합할 약병 개수(0~1 + 2 -> 2~3)
        } while (cntShowBottle == prevCntShowBottle);
        prevCntShowBottle = cntShowBottle;
        printf(" > %d번째 테스트 : ", i);

        int isIncluded = 0; // 진짜 발모제인지 확인용
        // 조합할 약병 번호 선택
        for (int j = 0; j < cntShowBottle; j++) 
        {
            int randBottle = rand() % 4; // 약병 번호 뽑기(0~3)
            if (bottle[randBottle] == 0) // 아직 선택되지 않은 약병이면
            { 
                bottle[randBottle] = 1; // 값을 0 → 1
                if (randBottle == treatment) 
                {
                    isIncluded = 1; // 1이면 해당 약병은 진짜 발모제
                }
            }
            else // 이미 선택된 약병이면 중복이므로 다시 선택
            {
                j--; // 반복 횟수 조정
            }
        }

        // 사용자에게 테스트 결과 표시
        for (int k = 0; k < 4; k++) 
        {
            if (bottle[k] == 1) 
            {
                printf("%d ", k + 1); // %d 뒤에 빈칸 하나 넣기
            }
        }
        printf("번 물약을 머리에 바릅니다.\n\n");

        if (isIncluded == 1) // 약병 조합에 발모제가 포함된 경우
        {
            printf(">> 성공! 머리카락이 났어요!!\n");
        }
        else // 약병 조합에 발모제가 포함되지 않은 경우
        {
            printf(">> 실패! 머리카락이 나지 않았어요. ㅠㅠ\n");
        }
        printf("\n   계속하려면 Enter를 누르세요. \n");
        getchar(); // (void) getchar();
    }
     
    // 사용자 입력받기
    printf("\n\n발모제는 몇 번일까요? ");
    int answer; 
    scanf_s("%d", &answer);
    if (answer == treatment + 1) // 정답일 때
    {
        printf("\n>> 정답입니다!\n");
    }
    else // 틀렸을 때
    {
        printf("\n>> 땡 ! 틀렸어요. 정답은 %d번입니다.\n", treatment + 1);
    }

    return 0;
}

0개의 댓글