본문 바로가기

CS50

CS50 배열

#include <stdio.h>

int main(void)
{
    char c1 = 'H';
    char c2 = 'I';
    char c3 = '!';
    printf("%n %n %n\n", c1, c2, c3);
}

출력 HI!

근데 이를 ASCII문자 10진수로 바꿀 수 있음

 

 

#include <stdio.h>

int main(void)
{
    char c1 = 'H';
    char c2 = 'I';
    char c3 = '!';
    printf("%i %i %i\n", (int) c1, (int) c2, (int) c3); 
}
#include <stdio.h>

int main(void)
{
    char c1 = 'H';
    char c2 = 'I';
    char c3 = '!';
    printf("%i %i %i\n", c1, c2, c3); //형변환 본래 %c였으나 %i로 입력해서 바꿈 
}

굳이 출력 인자에 삽입하는 변수에다가 일일이 형식지정자를 붙일 이유 없음

인자를 받는 %뒤에 i로 형식 바꿈하면 됨

출력이 72 73 33으로 바뀜

이를 형변환이라고 함

#include <stdio.h>
#include <cs50.h>

int main(void)
{
    //scores
    int score1=72;
    int score2=73;
    int score3=33;
    
    //Print average
    printf("Average:%i\n", (int score1 + int score2 + int score3)/3);
}

위 코드 작성시의 문제 점

1) 과목수가 바뀌면 너무 많은 부분을 고쳐야 함

2) 형식지정자가 int라서 부분 점수를 나타내기 힘듦(반올림)

 

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int scores[3];
    scores[0]=72;
    scores[1]=73;
    scores[2]=33;
    
    printf("Average:%i\n",(scores[0]+scores[1]+scores[2])/3);
}

int의 자료형을 가진 scores라는 배열 [3]= 3의 크기를 가지고있음

하단 scores들은 배열의 인덱스임 0부터시작한다.

이 코드 또한 여전히 문제점을 가지고 있음

 

#include <cs50.h>
#include <stdio.h>


//전역변수 코드 전반에 걸쳐서 바뀌지 않는 값
const int N = 3;

int main(void)
{
    //점수 배열 선언 및 값 저장
    int scores[N];
    scores[0]=72;
    scores[1]=73;
    scores[2]=33;
    
    //평균 점수 출력
    printf("Average:%i\n", (scores[0]+scores[1]+ scores[2])/N);
}

const 전역변수명은 일반적으로 대문자로 표현한다. 함수 바깥에서 선언

문제점

1. index마다 숫자를 지정해줘야하는 불편함

2.코드가 정적임

3.출력함수 부분이 너무 길다는 점

 


#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    int scores[n];
    
    for (int i = 0; i < n; i++)
    {
    	//몇번째과목의 점수인지 알려줌
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    printf("Average: TODO\n");
}

 

실행시 

Number of scores: 3

Score 1: 72

Score 2: 73

Score 3: 33

Average: TODO

 

여기서 문제 어떻게 하면 평균을 동적인 방식으로 계산해서 각각의 점수를 일일이 입력하지 않도록 할 수 있을까?

 

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    int scores[n];
    
    for (int i = 0; i < n; i++)
    {
    	//몇번째과목의 점수인지 알려줌
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    printf("Average: TODO\n");
}

//사용자가 입력한 값의 평균을 내기 위해서는 
//점수가 들어가는 배열의 길이를 알아야하고
//배열 그자체도 받아야 함
float average(int length, int array[])

여러 값들을 받으면 평균은 어떻게 계산하나요?

값들을 리스트(배열) 그 배열의 길이를 안다면 평균을 계산할때 어떻게 사용할 수 있는가?

배열의길이(과목수) 배열내의 값을 알 수 있음

 

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    int scores[n];
    
    for (int i = 0; i < n; i++)
    {
    	//몇번째과목의 점수인지 알려줌
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    printf("Average: TODO\n");
}

float average(int length, int array[])
{
    int sum = 0;//배열은 0부터 세기 때문
    for (int i= 0; i < length; i++)//length만큼 센다
    {
    	//sum에 다음 배열의 원소값을 적는다
        //각 반복마다 해당 값을 sum에 더할 수 있음
    	sum = sum + array[i];
    }
}

 

하단 값을 줄여서 나타낼 수 있는데

 

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    int scores[n];
    
    for (int i = 0; i < n; i++)
    {
    	//몇번째과목의 점수인지 알려줌
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    printf("Average: %f\n", average(n, scores));
}


//average는 두 개의 입력을 받는데 length라는 정수와 정수들의 배열을 받는다
//float은 반환값
float average(int length, int array[])
{
    int sum = 0;
    for (int i= 0; i < length; i++)//length만큼 센다
    {
    	sum += array[i];
    }
}

실행결과 오류

함수 프로토타입을 넣지 않아서

 

#include <cs50.h>
#include <stdio.h>

float average(int length, int array[]);

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    int scores[n];
    
    for (int i = 0; i < n; i++)
    {
    	//몇번째과목의 점수인지 알려줌
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    printf("Average: %f\n", average(n, scores));
}


//average는 두 개의 입력을 받는데 length라는 정수와 정수들의 배열을 받는다
//float은 반환값
float average(int length, int array[])
{
    int sum = 0;
    for (int i= 0; i < length; i++)//length만큼 센다
    {
    	sum += array[i];
    }
    return sum / length;
}

여전히 오류가 있는데 C에서는 

정수/정수 는 정수이다. 때문에 정수는 소수점 뒤으 숫자들을 저장할 수 없음

 

#include <cs50.h>
#include <stdio.h>

float average(int length, int array[]);

int main(void)
{
    int n = get_int("Number of Scores: ");
    
    //점수 배열 선언 및 사용자로부터 값 입력
    int scores[n];   
    for (int i = 0; i < n; i++)
    {
    	scores[i] = get_int("Scores %i: ", i + 1); //0부터 세는 걸 막기 위해 1을 붙여줌
    }
    
    //평균출력
    printf("Average: %f\n", average(n, scores));
}

//평균을 계산하는 함수
float average(int length, int array[])
{
    int sum = 0;
    for (int i= 0; i < length; i++)//length만큼 센다
    {
    	sum += array[i];
    }
    //형변환
    return (float) sum / (float) length;
}

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    string names[4];
    names[0] = "EMMA";
    names[1] = "RODRIGO";
    names[2] = "BRIAN";
    names[3] = "DAVID";
    
    printf("%S\n", names[0]);
    
    //배열의 인덱스 문자의 번째
    printf("%c%c%c%c\n", names[0][0],names[0][1],names[0][2], names[0][3])
}

출력 EMMA

      EMMA

만약 출력함수에 다섯번째 %i를 넣고 인자로 names[0][4]를 추가한다면

EMMA0로 출력(null-terminator 널 종단때문인지 아닌지는 모르겠음)

 

*string은 그 자체로 char열임

만약에 string s ="James"; 로 s를 정의했을때

s[0] s[1] s[2]...... char의 열이 생성되는 거임

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    string s = get_string("Input: ");
    printf("Output: ");
    for (int i = 0; ???; i++);
    {  
    	printf("%c", s[i]); 
    }
	printf("\n");
}

 

질문 for 루프에서 어떤 조건을 넣어야지 모든 글자를 다 출력했는지 여부를 알 수 있을까?

1)널 문자와 같은지 아닌지

2)문자열의 길이

 

둘다 해보자

1)널문자 

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    string s = get_string("Input: ");
    printf("Output: ");
    
    //s[i]가 /0과 같지 않을때 여기서 ''을 쓰는 이유는 \0 자체가 하나의 문자이기 때문이다
    for (int i = 0; s[i] != '\0'; i++)
    {  
    	printf("%c", s[i]); 
    }
    printf("\n");
}

결과

Input: EMMAOutput: EMMA

 

2)문자열의 길이

#include <cs50.h>
#include <stdio.h>
//strlen의 프로토타입 즉 선언은 string.h에 있음
#include <string.h>


int main(void)
{
    string s = get_string("Input: ");
    printf("Output: ");
    for (int i = 0; i < strlen(s); i++)//열의 길이를 재는 함수이다
    {  
    	printf("%c", s[i]); 
    }
    printf("\n");
}

결과

Input: EMMA

Output: EMMA

 

수정이 필요한 부분이 있음

 i < strlen(s)는 불리언표현임 그리고 strlen은 함수임 i가 굳이 열s의 길이 만큼 반복될 이유가 있을까?

어차피 strlen(s)는 계속 같은 값일텐데?

 

방법1

int n =strlen(s); 삽입 뒤

for 루프 문 조건 부분을 i < n으로 수정

 

or

방법2

삽입없이 for 루프에 int i = 0; 다음 n = strlen(s); 추가 for 구문 안에 4개의 값이 들어가는 것임

 

소문자를 대문자로 바꾸는 코드

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

int main(void)
{
    string s = get_string("Before: ");
    printf("After: ");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
    	if(s[i]>='a' && s[i] <= 'z')
        {
        	printf("%c", s[i] - 32);//대문자로 바꾸기 convert to uppercase
        }
        else
        {
        	printf("%c, s[i]");
        }
    }
    printf("\n");
}

ASCII에 따르면 대문자는 소문자보다 -32만큼 차이가 남

Before: emma

After: EMMA

 

소문자를 대문자로 바꿔줄 수 있는 함수를 찾아서 쓸 수도 있음

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

int main(void)
{
    string s = get_string("Before: ");
    printf("After: ");
    for(int i =0; n =strlen(s); i < n; i++)
    {
    	//toupper 소문자를 대문자로 바꾸는 함수
    	printf("%c", toupper(s[i]));
    }
    printf("\n");
}

결과 동일

 


 

#include <cs50.h>
#include <stdio.h>


//인자 개수 인자 배열
int main(int argc, string argv[])
{   
    //사용자로 하여금 프로그램이 실행되고 get_string 함수 호출을 기다리는 대신
    //그냥 명령 프롬프트에 바로 이름을 쓸 수 있게 하는 것이다
    if (argc == 2)
    {
    	printf("hello, %s\n", argv[1])
    }
    else
    {
    	printf("hello, world\n")
    }
}

명령 프롬프트 실행 ./argv David

hello, David

 

David를 입력하면 argc라는 배열에 들어가고 argc는 단어의 개수가 저장된다

 

#include <cs50.h>
#include <stdio.h>

int main(int argc, string argv[])
{
    //문제 있음
    //2인 이유: argv에서는 첨에 입력하는 프로그램의 이름이 [0]
    //그 다음에 입력하는 첫번째 인자가 [1]
    if (argc != 2)
    {
    	printf("missing command-line argument\n");
        return 1;
    }
    //문제 없음
    printf("hello, %s\n", argv[1]);
    return 0;
}

 

'CS50' 카테고리의 다른 글

CS50 컴파일  (0) 2022.02.01