#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;
}