능동적인 생각은 프로그래밍 공부에 큰 도움 3장 근의 공식은 어떻게 표현하나? 왜 정수와 실수를 구별하나? 실수와 정수를 더하면 오류가 날까? 문자열은 메모리 내부에 어떻게 표현할까? … 3장 기본형과 그들의 변형 연산자 그리고 그들의 우선순위와 결합 법칙 3.7절은 π를 추정하는 프로그램
3.1 데이터 형 C에서 모든 변수는 형을 가짐 프로그래머는 목적에 따라 적절한 형을 사용해야 함 형type C 제공형: char, int, float 그리고 그들의 여러 변형 (3장) 사용자 정의형: struct, typedef, enum (7장)
자료형이란 무엇인가? 자료형(data type) C 언어의 자료형 프로그램에서 표현 혹은 저장하는 데이터의 종류 혹은 유형 크기에 따라 문자형 char 정수형 short int long 부동소수형 float double long double C 언어의 자료형 분류
변수 자료형 변수이름; 변수(variable) 사용 전 변수 선언 데이터를 저장하는 데 사용되는 기억 장소의 이름이다. 변수 이름과 저장할 데이터 값의 유형(자료형)을 지정해야 한다. 자료형 변수이름; char c; short sum;
메모리와 변수 변수를 위한 메모리 할당 문자형 변수 c를 위해서는 1 바이트를 할당 1278 1279 10011010 c 1280 1281 1282 1283 1284 1285 1286 sum 10011010 c 변수를 위한 메모리 할당 문자형 변수 c를 위해서는 1 바이트를 할당 short 변수 sum에 대해서는 2 바이트를 할당 메모리와 변수
상수 상수(constant) 프로그램이 실행되는 동안 값이 변하지 않는 데이터 정수형 상수, 문자형 상수, 부동소수형 상수로 구분할 수 있다. 예 'A', 'x'는 문자형 상수 -10, 0, 55는 정수형 상수 3.14, 300.25는 부동소수형 상수
C의 기본 정수형의 범위 예(Microsoft Visual C/C++ 6.0) 크게 4개의 정수형 char, short, int, long 자료형 기억장소 최소값 최대값 char 8 비트 -27 = -128 27-1 = 127 short 16 비트 -215 = -32,768 215-1 = 32,767 int 32 비트 -231 = -2,147,483,648 231-1 = 2,147,483,647 long long long* 64 비트 -264 = -9,223,372,036,854,775,808 263-1 = 9,223,372,036,854,775,807 * long long은 MS Visual C/C++ 6.0에서는 지원되지 않음. 여기서 long long은 gcc 컴파일러의 예 C의 기본 정수형의 범위 예(Microsoft Visual C/C++ 6.0)
예제 1 정수형 종류에 따라 해당 변수에 다른 크기 기억공간 할당 자료형의 크기를 나타내는 sizeof() 연산자 실행결과: char 크기: 1 short 크기: 2 int 크기: 4 long 크기: 4
unsigned 정수형 0과 양의 정수만을 나타낼 수 있는 unsigned 정수형 음수를 표현할 수 없는 대신에 나타낼 수 있는 양의 정수가 두 배 자료형 기억장소 최소값 최대값 unsigned char 8 비트 28-1 = 255 unsigned short 16 비트 216-1 = 65,535 unsigned int 32 비트 232-1 = 4,294,967,295 unsigned long 64 비트 264-1 = 18,446,744,073,709,551,615 C의 unsigned 정수형의 표현범위
참고자료 %c, %d, %f, %s 가장 많이 쓰이는 서식 문자들 %o, %u, %x, %X 부호 없는 정수형 출력 %e, %E '부동소수점 표현 방식'에 의한 출력 3.1245e+2 3.1245×10+2 2.45e-4 2.45×10-4
부동소수형의 예(Microsoft Visual C/C++ 6.0) float, double, long double 부동소수점(floating-point)이란? 부동소수점에서 점(point)은 소수점을 말하며, 이 소수점이 수의 어느 위치에도 올 수 있으므로 부동소수점이라고 한다. 자료형 기억장소 최소값 최대값 float 4 바이트 7개의 유효숫자를 가지며, -1.0E+38의 근사값 7개의 유효숫자를 가지며, 1.0E+38의 근사값 double 8 바이트 15개의 유효숫자를 가지며, -1.0E+308의 근사값 15개의 유효숫자를 가지며, 1.0E+308의 근사값 long double 부동소수형의 예(Microsoft Visual C/C++ 6.0)
부동소수형 표현 float 형 자료의 저장과 표현 범위 double 형 자료의 저장과 표현 범위 부호 지수부 가수부 8바이트(64비트)
예제 2 실행결과: 0.1234567910432815600 0.1234567890123456800 float 크기: 4 double 크기: 8 long double 크기: 8
문자형 각 문자에 고유번호를 부여한 코드를 사용하여 표현한다. C에서는 ASCII 코드를 사용한다. ASCII(American Standard Code for Information Interchange) 128개의 문자를 7 비트를 사용하여 표현(8비트로 확장됨) 대문자(A, B, C 등등) 소문자(a, b, c 등등) 구두점(punctuation)(마침표, 세미콜론, 쉼표 등등) 숫자(digit)(0에서 9까지) 공백 문자(‘ ’) 특수 문자(&, |, \ 등) 제어 문자 열복귀(carriage return), 널(null), 문서-끝-표시자(end-of-text) 액센트(accent)가 있는 문자
ASCII 코드표 표 3.1) ASCII 코드 표
예제 3 실행결과: a 97 A 65 1 49 $ 36 + 43
3.1.1 기본 형과 그들의 변형 프로그래머는 이들을 충분히 이해해야 하며 적절한 형을 선택하여 사용해야 한다.
int의 변형 부호가 있느냐에 따라 signed int unsigned int 할당되는 바이트 수에 따라 (즉 표현 가능한 값의 범위에 따라) short int (short) // int 보다 적거나 같음 int long int (long) // int 보다 많거나 같음 long long // C99 표준에서 제공 int 사용 예 정수 상수의 진법 표현 십진수 (예, 182) 8진수 (예, 0266) 16진수 (예, 0xB6)
char의 변형 float의 변형 부호가 있느냐에 따라 signed char unsigned char 할당되는 바이트 수에 따라 (즉 표현 가능한 유효 숫자와 값의 범위에 따라) float의 유효 숫자는 7 자리 double의 유효 숫자는 15 자리 long double은 double보다 많거나 같음 실수 상수의 표현 예
오버플로우와 언더플로우 표현 가능한 최소값보다 작은 값이 발생하면 언더플로우 표현 가능한 최대값보다 큰 값이 발생하면 오버플로우 이들 오류가 발생하지 않도록 하는 일은 프로그래머의 몫 자동으로 검사해 주지 않는다. sizeof 연산자를 사용하면 도움이 된다. 형 또는 변수에 할당되는 바이트 수를 알 수 있음 사용 예 최대값과 최소값을 나타내는 기호 상수를 사용하면 도움이 된다. 예를 들어 INT_MAX는 int 형의 최대값
오버플로우 예 (factorial 계산)
연습 문제
3.1.3 형 변환 C는 혼합 연산에 너그럽다. 형 변환 규칙 낮은 표현을 높은 표현으로 변환 (즉 정보 손실이 적은 방향으로) 예를 들어, 정수와 실수가 혼합된 경우 정수를 실수로 변환. 왜? 예제 3.1
int와 char의 형 변환 C는 int를 char로 간주하기도 하고 int를 char로 간주하기도 한다. 처음에는 약간 혼란스러울 수 있으나 알고 보면 여러 장점 (3.2.1절) 캐스트 (형 변환) 연산자 강제로 (명시적으로) 형을 변화시킴
3.2 문자와 문자열 프로그램은 숫자 뿐 아니라 문자도 많이 다룬다. 웹 검색 엔진의 검색어 보고서 작성 등
3.2.1 문자 char 형 상수 예, ‘a’ // 작은 따옴표로 묶음 1바이트를 사용 ASCII 코드 표: 부록 B
문자를 정수로, 정수를 문자로 사용할 수 있음은 장점이다. (앞에서 계속) 둘째 예, 문자열에서 소문자 알파벳의 빈도 수 세기 라인 13: histogram[]의 0번 요소는 ‘a’, 1번 요소는 ‘b’, …
프로그램[3.2] 함수 버전 … …
연습 문제
3.2.2 문자열 0개 이상의 문자가 이어져 있는 것을 문자열이라 한다. 예, ”Hi, C.” // 큰 따옴표로 묶음 char 형 배열 사용 문자열 끝은 ‘\0’로 채움
문자열 길이 구하기 배열의 첫 요소부터 조사를 시작하여 ‘\0’가 나타날 때까지 센다.
문자열 길이 구하기의 함수 버전 라인 13-14를 한 줄로 줄여 쓸 수 있다. …
문자열 뒤집기 예, “Hi, C.” “.C ,iH”
연습 문제
3.2.3 문자 입출력 표준 라이브러리 함수 getchar()와 putchar() 문자 입출력에 혼란스런 상황이 있다. 아래 예제 코드에서 “20 A<ENTER>”를 입력했다면, 사용자 의도는 i에 20, a에 ‘A’ 하지만 i에 20, a에 ‘ ’이 입력됨. 왜? 이유는 버퍼 입출력에 있다. i에 20, a에 ‘ ’이 입력되고 버퍼에 “A\n”이 남음
버퍼 입출력 C 언어는 몇 가지 예외를 제외하고 입출력을 버퍼를 통해 한다. 프로그램 수행 속도 (매우 빠름)와 입출력 속도 (느림)의 차이를 완충시키기 위함
해결 방법 사용자가 “20A”를 입력함 사용자에게 이상한 걸 강요하는 꼴 또는, 아래 scanf()로 읽어 들임 (%d와 %c 사이에 공백이 있어야 함) 또는, getchar()대신 비 버퍼 입력 함수 getch()를 사용
한 줄의 문자열을 입출력 하는 gets()와 puts() 입출력의 추가 사항: 부록 A 정확한 입출력은 매우 중요하다.
3.3 사칙, 관계, 그리고 논리 연산자 사칙 +, -, … 관계 <, <=, ==, … 논리 &&, ||, … 그리고 재미있고 유용한 연산자 들 … 이들의 우선 순위와 결합 법칙 참/거짓 판정 규칙
3.3.1 연산자와 우선 순위
몇 가지 예 첫 번째 식은 항상 참이다. 왜?
3.3.2 프로그래밍 연습: 이차 방정식 풀기
라인 1-3을 코딩하면, 아래처럼 쓰면 안 된다. 왜?
C 코딩 하면
연습 문제
3.3.3 참/거짓 판정 C는 참/거짓 판정에 독특한 점이 있다. 첫째, 관계식과 논리식의 결과에 정수 값을 부여한다. 참은 1, 거짓은 0 그 값이 사칙 연산에 참여할 수도 있다. 둘째, 수치 값을 가지는 어떤 명령문이라도 참 거짓 판정에 참여할 수 있다. 0은 거짓, 0이 아닌 모든 수는 참
3.4 유용한 연산자들 C 언어는 연산자가 풍부하다는 특성이 있다. 독특한 연산자들 증감 연산자 비트 연산자 대입 연산자 조건 연산자
3.4.1 증감 연산자 ++는 1만큼 증가, --은 1만큼 감소 앞 증감은 ‘증감을 한 뒤에 값을 사용’ 뒤 증감은 ‘값을 사용한 후에 증감을 함’
증감 연산자는 프로그램을 간결하게 작성하는데 유용함 예, 문자열 뒤집기 함수
3.4.2 비트 연산자 비트 단위로 연산이 가능함
연습 문제
3.4.3 대입 연산자 자신에 어떤 값을 더하고 그것을 자신이 대입 받을 때, 이러한 형태를 취할 수 있는 연산자들
3.4.4 조건 연산자 피연산자가 세 개인 삼항 연산자 예, 일반적인 형태 유용한 경우 (둘 중 어느 것을 쓸 지는 프로그래머의 취향)
3.5 연산자 우선 순위와 결합 법칙
3.6 프로그래밍 스타일 플랫폼 프로그램 (소프트웨어) 실행을 지원하는 제반 환경 환경은 컴퓨터 기종, 운영 체제, 미들웨어 등을 포함 현대 컴퓨터 기술의 특성 중의 하나는 플랫폼의 다양성 이식성이 중요 . 이식성을 높이려면, 표준을 잘 따를 것 컴파일러에 따라 다름이 발생할 가능성이 있는 곳은 표시해 둠 sizeof() 연산자 사용 (예, 프로그램 [3.9]) 컴파일러에 따라 다르게 계산할 소지 있는 명령문 피함 (아래 예)
3.7 프로그래밍 연습: π 추정 원주율 π 추정은 고대에도 연구 대상 현재는 컴퓨터 기술의 도움의 1조 자리까지 알려짐 50자리까지 보여 주면,
3.7.1 면적을 이용한 방법 [-1,1]사이에 놓인 점을 충분히 많이 생성 시킴 원의 내부 (no_inside)와 외부 점 (no_outside)의 수를 셈 아래 예는 no_inside=27, no_outside=8
알고리즘으로 정리하면, 이 알고리즘은 수행 시간을 설정하여 점의 개수를 조절함
프로그램 설계 no_inside와 no_outside는 unsigned long int를 사용하자. 실수 변수는 double 형을 쓰자. (double은 유효 숫자가 15 자리)
시간 측정은 time()과 difftime() 함수로
오버플로우 발생 위험은? 라인 24-27에서 자체 점검 (ULONG_MAX를 넘지 않도록 함) 라인 33을 아래와 같이 바꾸면 위험하다. 왜? pi=(4.0*(double)no_inside)/(no_inside+no_outside); unit_rand()함수도 살펴 보자. 라인 40을 아래와 같이 하면 오동작한다. 왜? { return rand()/RAND_MAX;}
연습 문제
3.7.2 Plouffe 알고리즘 1995년 Simon Plouffe가 제안 예를 들어, n=2라면
아래 프로그램의 오버플로우 또는 언더플로우 위험은?
연습 문제