쉽게풀어쓴 C 언어 Express 제 4 장변수와자료형
이번장에서학습할내용 * 변수와상수의개념이해 * 자료형 * 정수형 * 실수형 * 문자형 * 기호상수사용 * 오버플로우와언더플로우이해 이번장에서는변수와각종자료형을살벼봅니다.
변수 Q) 변수 (variable) 이란무엇인가? A) 프로그램에서일시적으로데이터를저장하는공간 Q) 변수는왜필요한가? A) 데이터가입력되면어딘가에저장해야만다음에사용할수있다.
변수 = 상자 변수는물건을저장하는상자와같다. int 데이터 변수의타입 변수의이름
변수가만들어지는곳 변수는메인메모리에만들어진다. (Q) 만약메모리를변수처럼이름을가지고사용하자않고주소로사용하다면? 100번지에 0을대입하라 (A) 충분히가능하지만불편하다. 인간은숫자보다는기호를더잘기억한다.
변수와상수 변수 (variable): 저장된값의변경이가능한공간 상수 (constant): 저장된값의변경이불가능한공간 ( 예 ) 3.14, 100, A, Hello World! 12 12 변수 상수 (Q) 상수도이름을가질수있는가? (A) 보통상수는이름이없다. 이러한상수를리터럴 (literal) 이라고한다. 하지만필요하다면상수에도이름을붙일수있다. 이것을기호상수라고한다.
자료형 자료형 (data type): 데이터의타입 ( 종류 ) ( 예 ) 정수형데이터 (100) 실수형데이터 (3.141592) (Q) 디양한자료형이필요한이유는? (A) 상자에물건을저장하는것과같다.
자료형의종류 정수형 문자형 부호있음 부호없음 부호있음 부호없음 자료형 설명 바이트수 short short 형정수 2-32768~32767 범위 int 정수 4-2147483648~2147483647 long long형정수 4-2147483648~2147483647 unsigned short 부호없는 short형정수 2 0~65535 unsigned int 부호없는정수 4 0~4294967295 unsigned long 부호없는 long 형정수 4 0~4294967295 char 문자및정수 1-128~127 unsigned char 문자및부호없는정수 1 0~255 float 단일정밀도부동소수점 4 1.2E-38~3.4E38 부동소수점형 double 두배정밀도부동소수점 8 2.2E-308~1.8E308
변수의이름짓기 식별자 (identifier): 식별할수있게해주는이름 변수이름 함수이름 김영희 김철수
식별자를만드는규칙 알파벳문자와숫자, 밑줄문자 _ 로구성 첫번째문자는반드시알파벳또는밑줄문자 _ 대문자와소문자를구별 C 언어의키워드와똑같은이름은허용되지않는다. (Q) 다음은유효한식별자인가? sum _count king3 O O O n_pictures 2nd_try O X // 숫자로시작 dollor$ X // $ 기호 double X // 키워드
키워드 키워드 (keyword): C언어에서고유한의미를가지고있는특별한단어 예약어 (reserved words) 라고도한다. auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while
변수선언 변수선언 : 컴파일러에게어떤변수를사용하겠다고미리알리는것 자료형변수이름 ; 변수선언의예 char c; int I; double interest_rate; int height, width;
변수에값을저장하는방법 char c; // 문자형변수 c 선언 int i; // 정수형변수 i 선언 double interest_rate; // 실수형변수 interest_rate 선언 c = 'a'; // 문자형변수 c에문자 'a' 를대입 i = 60; // 정수형변수 i에 60을대입 interest_rate = 4.9; // 실수형변수 interest_rate에 82.9를대입
자료형변수이름 = 초기값 ; 변수의초기화 변수초기화의예 char c = a ; int i = 7; double interest_rate = 0.05;
변수선언위치 변수는함수의첫부분에서만선언할수있습니다. int main(void) { 변수선언 int count; int index; } count = 0; index = 1; int sum;... 일반문장 잘못된변수선언
정수형 short, int, long 가장기본이되는것은 int CPU 에따라서크기가달라진다. 16비트, 32비트, 64비트 (Q) 왜여러개의정수형이필요한가? (A) 용도에따라프로그래머가선택하여사용할수있게하기위하여
정수형의범위 int 형 short 형 long 형 보통 int 형과같음
예제 /* 정수형자료형의크기를계산하는프로그램 */ #include <stdio.h> int main(void) { short year = 0; // 0으로초기화한다. int sale = 0; // 0 으로초기화한다. long total_sale = 0; // 0으로초기화한다. year = 10; // 약 3만2천을넘지않도록주의 sale = 200000000; // 약 21억을넘지않도록주의 total_sale = year * sale; // 약 21억을넘지않도록주의 printf("total _ sale = %d \n", total_ sale); printf("short형의크기 : %d바이트\n", sizeof(short)); printf("int형의크기 : %d바이트\n", sizeof(int)); printf("long 형의크기 : %d 바이트 \n", sizeof(long)); } return 0; short형의크기 : 2바이트 int형의크기 : 4바이트 long형의크기 : 4바이트
signed, unsigned 수식자 unsigned 음수가아닌값만을나타냄을의미 unsigned int signed 부호를가지는값을나타냄을의미 흔히생략
오버플로우 #include <stdio.h> int main(void) { int x; unsigned int y; x = 2147483647; printf("x = %d\n",x); x = 2147483647 x+1 = -2147483648 x+2 = -2147483647 x+3 = -2147483646 y = 4294967295 y+1 = 0 y+2 = 1 y+3 = 2 printf("x+1 = %d\n",x+1); printf("x+2 = %d\n",x+2); printf("x+3 = %d\n",x+3); 오버플로우발생!! } y = 4294967295; printf("y = %u\n",y); // unsigned를출력하는형식지정자는 %u printf("y+1 = %u\n",y+1); printf("y+2 = %u\n",y+2); printf("y+3 = %u\n",y+3);
오버플로우 오버플로우 (overflow): 변수가나타낼수있는범위를넘는숫자를저장하려고할때발생
오버플로우 규칙성이있다. 수도계량기나주행거리계와비숫하게동작
정수상수 숫자를적으면컴파일러가가장작은자료형을자동으로선택 상수의자료형을명시하려면다음과같이한다. 접미사자료형예 u 또는 U unsigned int 123u 또는 123U l 또는 L long 123l 또는 123L ul 또는 UL unsigned long 123ul 또는 123UL 10 진법이외의진법으로도표기가능 int x = 10; // 10은 10진수이고 int형이고값은십진수로 10이다. int y = 010; // 010은 8진수이고 int형이고값은십진수로 8이다. int z = 0x10; // 010 은 16 진수이고 int 형이고값은십진수로 16 이다.
예제 /* 정수상수프로그램 */ #include <stdio.h> int main(void) { int x = 10; // 10 은 10 진수이고 int 형이고값은십진수로 10 이다. int y = 010; // 010은 8진수이고 int형이고값은십진수로 8이다. int z = 0x10; // 010은 16진수이고 int형이고값은십진수로 16이다. printf("sizeof(10l) = %d\n", sizeof(10l)); printf("x = %d y = %d z = %d\n", x, y, z); printf("x = %d x = %#o x = %#x\n", x, x, x); } return 0; sizeof(10l) = 4 x = 10 y = 8 z = 16 x = 10 x = 012 x = 0xa
기호상수 기호상수 (symbolic constant): 기호를이용하여상수를표현한것 ( 예 ) area = 3.141592 * radius * radius; area = PI * radius * radius; income = salary - 015 0.15 * salary; income = salary - TAX_RATE * salary; 기호상수의장점 가독성이높아진다. 값을쉽게변경할수있다.
기호상수의장점
기호상수를만드는방법 1 #define 기호상수이름 값 /* 기호상수프로그램 */ #include <stdio.h> #define PI 3.141592 기호상수정의 int main(void) { float radius, area, circumference; printf(" 반지름을입력하시요 :"); scanf("%f", &radius); area = PI * radius * radius; circumference = 2.0 * PI * radius; // 변수선언 // 입력안내문 // 사용자로부터반지름입력 // 면적계산 // 둘레계산 printf(" 반지름은 %f 입니다.\n", radius); // 반지름출력 printf(" 원의면적은 %f이고둘레는 %f입니다.\n", area, circumference); } return 0;
2const 키워드이용 기호상수를만드는방법 /* 기호상수프로그램 */ #include <stdio.h> 기호상수정의 int main(void) { const double TAX_RATE = 0.15; // 기호상수선언 double income, salary; // 변수선언 printf(" 월급을입력하시요 :"); scanf("%lf", &salary); // 입력안내문 // double형은 %lf로지정하여야함 income = salary -TAX_RATE * salary; // 순수입계산 printf(" 순수입은 %lf입니다.\n", income); // 순수입출력 } return 0;
정수표현방법 컴퓨터에서정수는이진수형태로표현되고이진수는전자스위치로표현된다. 0 0 1 0 1 0 0 0
정수표현방법 양수 십진수를이진수로변환하여저장하면된다. 음수 보통은첫번째비트를부호비트로사용한다. 문제점이발생한다.
음수를표현하는첫번째방법 첫번째방법은맨처음비트를부호비트로간주하는방법입니다. 양수와음수의덧셈연산을하였을경우, 결과가부정확하다. ( 예 ) +3 + (-3)
음수를표현하는첫번째방법 (cont.) 양수 0 과음수 0 이존재
음수를표현하는두번째방법 2의보수로음수를표현한다. 현재사용되는표준적인음수표현방법 2의보수를만드는방법
2 의보수로양수와음수를더하면
예제 /* 2 의보수프로그램 */ #include <stdio.h> int main(void) { int x = 3; int y = -3; 음수가 2 의보수로표현되는지를알아보자. printf("x = %08X\n", x); // 8 자리의 16 진수로출력한다. printf("y = %08X\n", y); // 8자리의 16진수로출력한다. printf("x+y = %08X\n", x+y); // 8자리의 16진수로출력한다. } return 0; x = 00000003 y = FFFFFFFD x+y = 00000000
문자형 문자는컴퓨터보다는인간에게중요 문자도숫자를이용하여표현 공통적인규격이필요하다. 아스키코드 (ASCII: American Standard d Code for Information Interchange) 8 비트를사용하여영어알파벳표현 ( 예 )! 는 33, A 는 65, B 는 66, a 는 97, b 는 98!"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ `abcdefghijklmnopqrstuvwxyz{ }~
문자변수 char 형의변수가문자저장 char c; char answer; char code; char 형의변수에문자를저장하려면아스크코드값을대입 code = 65; code = A ; // A 저장
예제 /* 문자변수와문자상수 */ #include <stdio.h> int main(void) { char code1 = 'A'; char code2 = 65; // 문자상수로초기화 // 아스키코드로초기화 } printf(" 문자상수초기화 = %c\n", code1); printf(" 아스키코드초기화 = %c\n", code2); 문자상수초기화 = A 아스키코드초기화 = A (Q) 1 과 1 의차이점은? (A) 1 은정수상수이고 1 은문자상수이다.
제어문자 인쇄목적이아니라제어목적으로사용되는문자들 ( 예 ) 줄바꿈문자, 탭문자, 벨소림문자, 백스페이스문자 제어문자를나타내는방법 아스키코드를직접사용 char beep = 7; printf("%c" %c, beep); 이스케이프시퀀스사용 char beep = \a ; printf("%c", beep);
이스케이프시퀀스 제어문자이름 제어 문자 값 의미 표기 널문자 \0 0 문자열의끝을표시 경고 (bell) \a 7 " 삐 하는경고벨소리발생 백스페이스 (backspace) \b 8 커서를현재의위치에서한글자뒤로옮긴다. 수평탭 (horizontal tab) \t 9 커서의위치를현재라인에서설정된다음탭위치로옮긴다. 줄바꿈 (newline) \n 10 커서를다음라인의시작위치로옮긴다. 수직탭 (vertical tab) \v 11 설정되어있는다음수직탭위치로커서를이동 폼피드 (form feed) \f 12 캐리지 return) 리턴 (carriage 주로프린터에서강제적으로다음페이지로넘길때사용된다. \r 13 커서를현재라인의시작위치로옮긴다. 큰따옴표 \ 34 원래의큰따옴표자체 작은따옴표 \ 39 원래의작은따옴표자체 역슬래시 (back slash) \\ 92 원래의역슬래시자체
예제 /* 이스케이프시퀀스 */ #include <stdio.h> int main(void) { printf(" 이스케이프시퀀스는 \\ 와의미를나타내는글자를붙여서기술 \n"); printf("'\\a' 는경고를나타내는제어문자이다. \n"); printf("'\\007' 로도표현이가능하다. \n"); printf(" 경고를출력해보자 '\\007' 을출력한다 \007 \n"); } 이스케이프시퀀스는 \ 와의미를나타내는글자를붙여서기술 '\a' 는경고를나타내는제어문자이다. '\007' 로도표현이가능하다. 경고를출력해보자 '\007' 을출력한다
부동소수점형 컴퓨터에서실수는부동소수점형으로표현 소수점이떠서움직인다는의미 과학자들이많이사용하는과학적표기법과유사
실수를표현하는방법 #1 고정소수점방식 정수부분을위하여일정비트를할당하고소수부분을위하여일정비트를할당 전체가 32 비트이면정수부분 16 비트, 소수부분 16 비트할당 ( 예 ) 3.14 과학과공학에서필요한아주큰수를표현할수없다
실수를표현하는방법 #2 부동소수점방식 표현할수있는범위가대폭늘어난다. 10-38 에서 10 +38
부동소수점형
/* 부동소수점자료형의크기계산 */ #include <stdio.h> 예제 int main(void) { float x = 1.234567890123456789; double y = 1.234567890123456789; printf("float 의크기 =%d\n", sizeof(float)); printf("double의크기 =%d\n", sizeof(double)); printf("long double의크기 =%d\n", sizeof(long double)); } printf("x = %30.25f\n",x); printf("y = %30.25f\n",y); return 0; float의크기 =4 double의크기 =8 long double의크기 =8 x = 1.2345678806304932000000000 y = 1.2345678901234567000000000
부동소수점상수 일반적인실수표기법 3.141592(double 형 ) 3.141592F(float형 ) 지수표기법 1.23456e4 = 12345.6 1.23456e-3 = 0.00123456 유효한표기법의예 1.23456 2. // 소수점만붙여도된다..28 // 정수부가없어도된다. 0e0 2e+10 // + 나 -기호를지수부에붙일수있다. 9.26E3 // 9.26e3 //
부동소수점오버플로우 #include <stdio.h> int main(void) { float x = 1e39; printf("x = %e\n",x); } 숫자가커서오버플로우발생 C:\CPROGRAM\test\test.c(5) : warning C4056: overflow in floating-point constant arithmetic
#include <stdio.h> 부동소수점언더플로우 int main(void) { float x = 1.23456e-38; float y = 1.23456e-40; float z = 1.23456e-46; 숫자가작아서언더플로우발생 } printf("x = %e\n",x); printf("y = %e\n",y); printf("z = %e\n",z); x = 1.234560e-038 y = 1.234558e-040 z = 0.000000e+000
부동소수점형사용시주의사항 오차가있을수있다! #include <stdio.h> int main(void) { double x; 5.0은부동소수점수가저장할수있는한계떄문에저장되지않는다. } x = (1.0e20 + 5.0)-1.0e20; 10 printf("%f \n",x); return 0; 0.000000
Q & A