본문 바로가기

컴퓨터 언어/C언어

홍정모 C언어_printf(). scanf().오버플로우

21/01/07

 

컴퓨터에서는 main 함수부터 실행 => main의 (return)값을 운영체제가 받아간다.

printf =>함수 호출. call or invoke

 

자료형이 필요한 이유

1. 계산 맞춰주기(ex.소수점, 정수)

2. 숫자 크기마다 필요로하는 메모리공간 크기가 달라짐 -> 자료형으로 미리 메모리 사이즈 할당

printf() %

\n 다음줄

 

#include <stdio.h>

int main()
{
	int x, y, z;

	x = 1; y = 4;
	z = x + y;

	printf("%i+%i=%i", x, y, z);

	return 0;
}

 

함수

 

#include <stdio.h>

void say_hello(void);

int main(){
	say_hello();
	return 0;
}

void say_hello(void){
	printf("Hello, World!\n");
	return;
}

 

 

scanf() &: ampersand=and

 

보안 단계 설정 이런거 때문에 scanf 함수는 오류뜸

해결법1. 

해결법 2. 속성 전처리기에 미리 #define _CRT_SECURE_NO_WARNINGS

해결법 3. scanf를 scanf_s로 고치기

 

scanf("%d", &i); 에서 i의 주소를 받아서, 그 주소에 할당된 메모리 값이 입력한 값으로 변경되는 것임

값을 저장할 변수의 주소

 

 

 

21/01/09

 

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(){
	int i = 0, j = 0, sum=0;

	printf("Input Two integers\n");
	scanf("%d%d", &i,&j);
	
	sum = i + j;
	printf("%d plus %d = %d\n", i,j,sum);
	return 0;
}

 

 

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(){
	int won = 0;
	int dollar = 0;

	printf("Input won\n");
	scanf("%d", &won);

	dollar = won * 0.00089;
	printf("Dollar= %d", dollar);

	return 0;
} // 1000입력해보자. dollar=0으로 출력 오류

int won=0;

int dollar=0;

dollar =won *0.00089;

 

dollar 정수형 자료형으로 써줬는데 소수점 곱해줘서 계산 제대로 안되는것

 

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(){
	float won = 0.0f;
	float dollar = 0.0f;

	printf("Input won\n");
	scanf("%f", &won);

	dollar = won * 0.00089f;
	printf("Dollar= %f\n", dollar);

	return 0;
}

float won =0;

float dollar=0;

dollar =won *0.00089f; => won과 0.00089 자료형이 다르니까, float로 맞춰주기 위해 0.00089f로.

 

%d => %f 로 바꿔줘야함 주의

 

 

 

정수 integers 와 실수 real numbers

정수: 2진수

실수: 2진수, 부동 소수점 표현법 사용 floating point

0.314E1 =0.314 * 10^1 =0.314e1= 31.4E-1 =0.314*10^-1

 

 

8비트 부호 있는 정수. Unsigned

2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0

8비트 부호 있는 정수. Signed

앞의 한 비트를 +- 부호 표현에 사용 (0:양수,1:음수)

2의 보수 표현법이 일반적

부호있는 정수와 범위가 다름

+/- 2^6 2^5 2^4 2^3 2^2 2^1 2^0

부동 소수점 수

+/- 부호 (Sign) 지수(Exponent) 분수(Fraction) (실제 숫자 부분)

ex. +/ 2/ 0.3145 => 0.3145 * 10^2 = 31.45

 

32bit Single Precision, 64bit Double Precision 

메모리 크기 차이

 

 

 

21/01/10

 

정수의 오버플로우

sizeof: 자료형이나 변수의 메모리공간 사이즈를 알려주는 연산자

 

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(){
	unsigned int i = 0;

	printf("%u\n",sizeof(unsigned int)); //%u = unsigned integer
	printf("%u\n", sizeof(i));
	//sizeof: 자료형이나 변수의 메모리공간 사이즈를 알려주는 연산자
}

변수가 가질 수 있는 최소~ 최대값 사이에서 사용해야 

=> 그 범위를 넘어가면(오버플로우) 메모리가 담당할 수 없기 때문

 

unsigned는 부호가 없기 때문에 최소값은 무조건 0

unsigned는 %d아닌 %u를 사용해줘야함!

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(){

	unsigned int i = 0b11111111111111111111111111111111; 
	//0b= binary 이진수라는 의미
	//11111111111111111111111111111111의 값을 나타냄. 최대값

	printf("%u\n", i); //unsigned는 %d아닌 %u를 사용해줘야함!
}
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h> //각각의 자료형이 가지는 최대, 최소값을 알려주는 헤더파일

int main(){
	unsigned int u_max = UINT_MAX; //MAX=매크로. 위의 헤더파일에 속해있는 듯
	unsigned int u_min = 0;
	signed int i_max = INT_MAX; 
	signed int i_min = INT_MIN;

	printf("max of unit=%u\n", u_max);
	printf("max of int=%d\n", u_min);
	printf("max of unit=%u\n", i_max);
	printf("max of int=%d\n", i_min);

	return 0;
}
/*max of unit=4294967295
max of int=0
max of unit=2147483647
max of int=-2147483648*/
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h> //각각의 자료형이 가지는 최대, 최소값을 알려주는 헤더파일
#include <stdlib.h> // standard library

int main(){
	unsigned int u_max = UINT_MAX+1; 

	//i to binary representation.
	//변수가 담고 있는 값을 이진수로 바꿔주는 코드
	char buffer[33];//문자를 33개 메모리에 나란히 저장할 수 있는 배열을 선언
	//4바이트*8비트=32비트 +1로 33을 사용(추후 설명)
	_itoa(u_max, buffer, 2); 

	//print decimal and binary
	printf("decimal:%u\n", u_max);
	printf("binary:%s\n", buffer);

	return 0;
}
/*decimal:0
binary:0*/

//1111+1=10000 인데 4비트라서 1이 사라져서 0000이 되는 꼴
//최대값+1= 0

unsigned int u_max=UINT_MAX+1;//위처럼 최대값에서 +1하면

(오버플로우)최소값 0이 출력된다.

 

1111+1=10000 인데 4비트라서 1이 사라져서 0000이 되는 꼴
최대값+1= 0

 

unsigned int u_min=0-1; //최소값에서 -1 하면

(오버플로우)최대값이 출력된다.

 

0000 -1 =  앞에 마치 1이 붙어서 10000-1 =1111 이 되는 꼴

 

1byte=8bit=2^8크기

각 자료형마다 값의 범위가 달라서, 잘못 쓸 경우 오버플로우가 발생함 주의

 

고정너비 정수 fixed-width integers

위 표처럼 자료형의 최소크기만 지정해줬기 때문에, 프로젝트마다 자료형의 크기가 다르면 어떡함?

이를 예방하기 위해 고정너비 정수 사용

 

//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//#include <stdint.h>//also included in inttypes.h
#include <inttypes.h> //알맞은 형식지정자를 지정해주는데 도움

int main(){
	int i;
	int32_t i32; //32bit integer로 고정
	int_least8_t i8; //smallest 8bit
	int_fast8_t f8; //fastest minimum
	intmax_t imax; //biggest signed integers
	uintmax_t uimax;//biggest unsigned integers

	i32 = 1004;

	printf("me32=%d\n", i32);
	printf("me32=%" "d" "\n",i32);
	printf("me32=%" PRId32 "\n", i32);//printf 때, 어떤 형식지정자를 쓸지 모르면 PRI+비트수 -> 정의로 이동해서 찾을 수 있다.

	return 0;
}

 

 

 

8진수 16진수

#include <stdio.h>

int main(){
	unsigned int decimal = 4294967295;
	unsigned int binary = 0b1111111111111111111111111111111111111111;//앞에 0b붙이면 2진수라는 뜻
	unsigned int oct = 037777777777;//앞에 0붙이면 8진수라는 뜻
	unsigned int hex = 0xffffffff;//앞에 0x붙이면 16진수라는 뜻.

	printf("%u\n", decimal);
	printf("%u\n", binary);
	printf("%u\n", oct);
	printf("%u\n", hex);
	/*모두 4294967295로 출력*/

	printf("%o %x %#o %#x %#X",decimal, decimal, decimal, decimal,decimal);//#기호로 진수를 명확히 표현하도록
	//37777777777 ffffffff 037777777777 0xffffffff 0XFFFFFFFF

	return 0;
}

 

 

'컴퓨터 언어 > C언어' 카테고리의 다른 글

홍정모 C언어_문자형  (0) 2021.01.10