2. C언어

Elenaljh·2023년 6월 20일
0

CS50

목록 보기
2/14

Welcome file
Welcome file

1. C언어

1. 기본

1. 라이브러리 참조

#include <stdio.h>

cf. stdio.h는 printf() 함수가 저장되어있는 라이브러리임.

2. 코드 본문

int main(void){
	본문 입력
}

Error: expected identifier of '('
-> int main(void)가 입력되지 않았을 때 이런 오류 터짐

3. printf()

printf("Hello, world\n");

4. 컴파일

  • 컴파일러: 소스코드(C, 자바 등)을 머신코드(이진법으로 작성되어 컴퓨터가 읽을 수 있는 코드)로 바꿔줌
  • clang: C언어 컴팡일러 이름
  • 컴파일링 하는 법
    - 어려운 방법: clang [-o 머신코드파일이름] [소스코드 파일이름] [-l 라이브러리 이름]
    -쉬운 방법: make [머신코드파일이름]

5. 값 입력받아 변수에 저장하기 (scanf)

  • 정수값 입력받기
int n;
scanf("%i", &n);

cf. 변수 선언할 때 앞에 자료형 알려줘야 함 ex. n; (X), int n; (O)

  • 문자 입력받기: 이건 까다로우니 따로 정리함

어쨌든 핵심은 자료형 잘 맞춰서 입력해야 한다는 것임 (int n 과 %i)

2. 문자열

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

int main(void){
	string a = "apple";
	printf("I want to eat %s\n", a);
}

%s는 a를 받아옴. 출력결과는 I want to eat apple임.

3. 조건문과 루프

1. counter 만드는법

int counter;선언 후

  • counter = counter + 1;
  • counter += 1;
  • counter++;

2. 조건문

if (x<y)
{
	본문
} 
else if (x==y)
{
	본문
} 
else 
{
	본문
}

cf. 짝수, 홀수 판단하기

#include  <stdio.h>  //기본함수 라이브러리

  

int  main(void)  //초록깃발
{ 
	int n; //정수형 변수 n 선언
	printf("Type a number.: "); //정수 입력하라고 물음
	scanf("%i",  &n); // 정수 입력받아서 변수 n에 할당
	if(n%2==0)
	{
		printf("%i is an even number.\n", n); // n을 2로 나눴을 때 나머지가 0이면 짝수
	}
	else
	{
		printf("%i is an odd number.\n", n); // 나머지 경우는 홀수
	}
}

2.1. switch문

switch() 괄호 안의 값과 같은 case의 코드 실행시킴
'동등조건'만 검사 가능(대소조건 비교 불가)하지만 if보다 작동속도가 빠르다.

int  main(void)
{
	int score =  90;
	switch (score/10)
	{
		case  9:
			printf("통과\n");
			break;
		case 8:
			printf("낙제\n");
			break;
		default:
			printf("낙제\n");
	}
}

score/10의 값이 9일때는 "통과" 출력, 8일때는 "낙제" 출력, 그 외의 값일때는 "낙제"출력

2.2. 3항 연산자

int  main(void)
{
	int x =  50;
	string y = x>3  ?  "success"  :  "fail";
	printf("%s\n", y);
}

x가 3보다 크면 y에 "success"저장, 3보다 작으면 y에 "fail" 저장함.

3. 루프 1 (while문)

hello, world를 50번 입력하는 코드

int i = 0;
while (i < 50)
{
	printf("hello, world");
	i++;
}

cf. do-while문

int i = 0;
do 
{
	int n;
	printf("positive integer: ");
	scanf("%i", &n);
} 
while (i<1);

while문: 조건이 충족되지 않으면 아무것도 실행안됨
do-while문: 조건이 충족되지 않아도 한번은 실행됨

4. 루프 2 (for문)

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

int  main(void)
{
	for(int i=0; i<10; i++)
	{
	printf("개발공부는 재미있다.\n");
	}
}

4. 자료형, 형식지정자, 연산자

1. 자료형

  • bool: ex. <, >, <=. >=, ==, !=, &&(and), ||(or)
  • char: 문자 1개 ex. y/n
  • float: 실수 (32bit)
  • double: 실수(64bit로 float보다 소수점 뒤에 더 많은 숫자 가짐)
  • int: 정수(40억까지 셀 수 있음)
  • long: 정수(int보다 더 많은 비트 사용하기 때문에 더 큰 수 셀 수 있음. 구글과 같은 대형 it기업에서 사용)
  • string: 문자

2. 형식지정자

  • %c: char
  • %f: float, double
    - %.nf: 소수점 아래 n번째 자리까지만 표기
  • %i: int
  • %li: long
  • %s: string

3. 연산자

  • /: 나눗셈
  • %: 나머지
  • //: 주석
  • &&: and
  • ||: or

5. 사용자 정의 함수, 중첩 루프

1. 사용자 정의 함수

예시 (cough)

#include  <stdio.h>

// 함수 프로토타입
void  cough(int n);    //입력이 정수이므로 int n 쓴다. 

// 본문
int  main(void)
{
	int a;
	printf("how many times this computer cough?");
	scanf("%i",  &a);
	cough(a);
}

// 함수 세부 정의 
void cough(int n)
{
	for (int i=0;i<n;i++)
	{
		printf("cough\n");
	}
}

1.1. 나만의 함수 만들기

  1. 함수 프로토타입: 코드 맨 윗부분에 정의할 함수명을 써준다.
    void function(void)
  • 앞부분 void: 함수 출력 결과. 출력물이 없다면 void를 쓰는데, 출력물(return)이 있다면 출력물의 자료형을 써야 한다
  • 예시
int get_positive_int(void)   // 출력물이 정수이므로 int
{
	int n;
	do
	{
		n=get_int("Positive Integer: ");
	}
	while (n<1);
	return n;   //출력물 존재
}

이 함수의 경우 출력물(n)이 정수이기 때문에 함수를 정의할 때 앞에 void가 아닌 int를 붙인다.

  • 뒷부분 void: 함수의 괄호 안에 입력하는 것의 자료형을 쓴다. 괄호 안에 아무것도 입력하지 않으면 void, 입력하는 것이 있으면 int나 string 등 자료형을 써야 함.
  • 예시: 위의 cough(n)의 코드를 참고
  1. int n; : 정수 n이라는 변수 선언. 아무 값도 할당하지 않았으므로 쓰레기값(Garbage Value)가짐.

2. 중첩 루프

예시: 마리오 벽돌 만들기

#include  <stdio.h>

// 함수 프로토타입
void  mario(int);

// 본문 
int  main(void)
{
	int a;
	printf("width: ");
	scanf("%i",  &a);
	mario(a);
}  

// 함수 세부정의
void  mario(int n)
{
	for (int i=0;i<n;i++)  //i= 행의 수
	{
		for(int j=0;j<n;j++)  //j= 열의 수 
		{
		printf("ㄱ");
		}
	printf("\n");
	}
}

6. 하드웨어의 한계

1. RAM(Random Access Memory)

  • 실행중인 프로그램은 RAM에 일시적으로 저장된다
  • 유한한 크기의 비트만 저장할 수 있기 때문에 부정확한 결과를 내기도 한다

2. 부동 소수점 부정확성(Floating-point imprecision)

float로 소수점 아래 50자리까지 1/10 결과 출력하기

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

// floating-poin imprecision
int  main(void)
{
	float x =  get_float("x: ");
	float y =  get_float("y: ");
	printf("x/y = %.50f", x/y);
}

결과

x: 1
y: 10
x/y = 0.10000000149011611938476562500000000000000000000000$ 

0.100000000000000000000000000000.. 이 나와야 하는데 이상한 숫자가 나옴. 그 이유는 float에서 저장 가능한 비트 수가 유한하기 때문에 부정확한 결과가 나오는 것임.

3. 정수 오버플로우 (Integer Overflow)

2의 거듭제곱 결과 출력하기

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

// Integer Overflow
int  main(void)
{
	for (int i=1;;i*=2)
	{
		printf("%i\n",i);
		sleep(1);   //1초간 멈추게 하는 함수
	}
}

결과

268435456
536870912
1073741824
Error.c:8:20: runtime error: signed integer overflow: 1073741824 * 2 cannot be represented in type 'int'
-2147483648
0
0
0
0
0
0

int에서는 32bit밖에 저장할 수 없기 때문에 10억 이상의 숫자는 저장 불가능. 예를 들자면 10진법으로 세 자리 숫자밖에 표현 불가능한 프로그램에서 1000 이상의 숫자는 오른쪽 세자리, 즉 0밖에 표현 불가능한 원리라고 보면 됨.

3.1. 정수 오버플로우의 예시

  1. Y2K 문제: 20세기에 연도를 마지막 두 자리로 저장하는 관습이 있었음. 2000년이 되면 00년도가 되는데 이는 1900년으로 인식되는 문제가 생김. 결국 수백만달러를 투자해 메모리 확장 활용.
  2. 보잉 787에서 구동 후 248일(대략 1/100초 단위로 환산했을 때 2^32이었음. -> 32bit)이 지나면 모든 전력을 잃는 문제.

0개의 댓글