관리 메뉴

흰둥씨의 개발장

[모두를 위한 컴퓨터 과학(CS50 2019)] 배열 본문

[오늘의 공부]/CS

[모두를 위한 컴퓨터 과학(CS50 2019)] 배열

돈워리비해삐 2023. 6. 17. 03:52

문자의 형변환

#include <stdio.h>

int main(void)
{
    char c1 = 'H';
    char c2 = 'I'; //char는 ''single quotes사용필수(string은 "") 
    char c3 = '!'; 
    printf("%i%i %i\n", (int)c1,(int)c2,(int)c3); //c1,c2,c3을 int로 형변환해서 프린트
    //7273 33
    //printf("%i%i %i\n", c1,c2,c3); 위 와 똑같은 결과 볼수 있음
}

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

int main(void)
{
    int s1 = 72;
    int s2 = 73;
    int s3 = 33;
    printf("Average : %i\n", (s1+s2+s3)/3);
}

위와 같은 코드 디자인은 좋지 않음 (아래와 같이 개선의 여지가 있음)

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

const int N = 3 ;  //상수로 선언하여 변하지 않는 값 지정 
int main(void)
{
    int scores[N]; //3개의 자리를 가진 배열 선언 
    scores[0] = 72; //할당
    scores[1] = 73;
    scores[2] = 33;
    printf("Average : %i\n", (scores[0]+scores[1]+scores[2])/N);
}

 


사용자에게 배열의 length와 배열 구성값 받아서 평균 출력하기 (3개로 구성된 배열 이면 array[0]...array[2]까지 값 받아 배열생성)

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

float average(int length, int array[]);  //함수 프로토 타입

int main(void)
{
  
    int n = get_int("Scores:  ");  // 사용자로부터 점수의 갯수 몇 개할건지 입력받음 
    int scores[n];                 // n개로 구성된 배열 선언

    for (int i = 0; i < n; i++)
    {
        scores[i] = get_int("Score %i: ", i + 1); //사용자에게 score[0+1]...scores[n+1]까지 값 입력받아 할당함
    }

    printf("Average: %.2f\n", average(n, scores)); // average함수호출하여 n과 scores전달해서 평균값 출력 
                    //%.2f는 flaot, 소숫점이하 2자리까지
}


float average(int length, int array[]) //배열이 몇개인지와 배열을 받아 평균값구해서 float로 반환
{
    int sum = 0;
    for (int i = 0; i < length; i++)
    {
        sum += array[i]; //합계구함 
    }
    return (float) sum / (float) length; //평균구하고 형변환
    //return sum / length 라고 만 적으면 정수/정수= 정수 이기 때문에 반환값이 float라 에러뜸
}

string은 char의 배열과 같음 
ㄴ정해진 크기를 가질수 없음(문자열 길이에 따라 달라짐)
ㄴ그래서 \0 (널 종단 문자)이나 \n 을 통해 문자열의 크기를 정해줌
ㄴprintf에게 string출력요청하면 널종단 문자전까지 출력함

string s = "Hi!\0";  // \0 는 null terminating char로 문자열이 끝났다는 것 알림
s[0];  //H  인덱스로 접근가능
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    string names[4];
    names[0] = "EMMA";
    names[1] = "WATSON";
    names[2] = "BRIAN";
    names[3] = "MAC";
    
    printf("%s\n", names[0]); //EMMA
    printf("%c%c%\n", names[0][0],names[0][1]); //names[0]은 EMMA이기 때문에 이자체를 배열로 취급하여
						//names[0][0]은 E, names[0][1]은 M이다.
}

두번째 printf를 아래와 같이 수정하면? 

{
	string names[4];
    	names[0] = "EMMA";

(중략...)

    printf("%c%c%c%c%i\n", names[0][0],names[0][1],names[0][2],names[0][3],names[0][4],names[0][5]);

//EMMA의 길이보다 하나더 출력하는 대신, 없는 문자는 %i로 하면
//EMMA0이 출력됨
}

사용자에게 문자열입력받아서, output으로 출력해주기

#include <cs50.h>
#include <stdio.h>
#include <string.h> //strlen같은 문자열 관련 함수들 라이브러리 

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

문자열의 길이 strlen(s)을 for문의 조건에 넣어서 계속 값을 확인하게 하는 것보다, (처리속도가 더 향상됨)
변수에 저장해서 기억하게 한뒤 계속 활용하게 하는 것이 더 좋음(저장공간이 좀더 소요됨)

#include <cs50.h>
#include <stdio.h>
#include <string.h> //strlen같은 문자열 관련 함수들 라이브러리 

int main(void)
{
    string s = get_string("Input : ");
    printf("Output: ");

     //int n = strlen(s);   변수에 저장
    for(int i =0, n = strlen(s); i < n ; i++)  //위에 변수선언한것과 똑같이동작함, 변수을 for문의 조건에 대입 
    {
        printf("%c", s[i]);
    }
    printf("\n");
}

문자를 입력받아서, 대문자로 바꿔줌

#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++)
    {
        //소문자는 대문자보다 32더 큼 (아스키코드 사이트 참조)
        if(s[i] >= 'a' && s[i] <= 'z') //s[i]가 소문자이면
        {
            printf("%c", s[i]-32);//대문자로 변환(소문자-32=대문자)
        }
        else           //대문자이면
        {
            printf("%c", s[i]);//그대로 출력함
        }
    }
    printf("\n");
}

 

 

유용한 프로그래밍 도구 정리 사이트(CS50도움말)

다른사람이 만들어준 함수이용해서 위의 로직 똑같이 구현하기 

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h> //uppercase로변환해주는 함수 내장라이브러리


int main(void)
{
    string s = get_string("Before: ");
    printf("After:  ");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c", toupper(s[i]));
    }
    printf("\n");
}

 

command line- argument(명령행 인자)

명령행 인자가 없는예 

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

int main(void) //메인 함수에서 명령행 인자(command line-argument)가 필요없다고 선언
{
    ...
}

 

명령행 인자가 있는 예

//argv.c파일 

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

int main(int argc, string argv[]) //정수 argc, 문자열로 구성된 배열 argv를 명령행 인자로 받음
{
    if(argc == 2)
    {
        printf("hello, %s\n", argv[1]);
    }
    else 
    {
        printf("hello, world\n");
    }
}

위와 같이 입력후 컴파일해서 파일을 실행하면 ?

$./argv     // hello, world
$./argv jin //hello, jin

 


C의 main함수는 기본적으로 반환값을 가져서 0을 반환함(0은 문제 없음을 의미)

//argv.c

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

int main(int argc, string argv[]) 
//argv를 컴파일하고 실행할 때
//argv에서 처음 입력하는 프로그램의 이름이 argv[0]에 저장되고
//사용자가 argv다음에 입력하는 첫번째 인자를 argv[1]에 저장한다.
{
    if(argc != 2)   //이 조건문은 "사용자가 첫번째 인자를 입력하지 않으면"을 검사하는 것
    {
        printf("명령행 인자가 없습니다.\n");
        return 1; //문제 있어서 1을 표시하고 종료 
    }
    printf("hello, %s\n", argv[1]); //명령행 인자가 정상 입력되었을때
    return 0;    //문제 없어서 0을 표시하고 종료
}