제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습
C 언어 프로그래밍 실습에 앞서 실습에 앞서 몇 가지 사항을 정리해 보자. 함수 입출력의 자료형 선언 함수 리턴 값을 생략한 경우 scanf() 주소 연산자와 printf() 자료형 Visual C++ 에서 C4996 에러 처리 막는 법
함수 입출력의 자료형 선언 “함수 리턴 결과 형식” main(“매개변수 입력 형식”) 에러가 나는 경우 int main(int) int main(void) = int main() void main(void) = void main() void main(int) 에러가 나는 경우 void main() { return 0; } void ☞ 자료형 없음 int ☞ 자료형 정수 ()안 void는 생략 가능 함수 선언할 때 리턴 값의 자료형이 없다고 했는데 함수 결과 값을 리턴할 때 자료형을 int 로 하여 에러
함수 리턴 값을 생략한 경우 다음 프로그램을 작성해 보자. return 0; ☞ 함수 리턴 값이 없으면 안 적어도 무관 #include <stdio.h> int main() { printf("안녕하세요? \n\n"); return 0; } return 0; ☞ 함수 리턴 값이 없으면 안 적어도 무관 컴파일러가 자동으로 에러를 수정해 주기 때문 함수 결과 값을 리턴할 것이 없는데, 꼭 리턴 명령을 써주어야 하나?
scanf() 주소 연산자와 printf() 자료형 변수의 주소를 구하는 연산자 & (ex.) scanf("%d", &src); ☞ &(변수명) = (변수의 주소) printf() 의 자료형 중 %d decimal ☞ 10진 정수 %u unsigned ☞ 부호 없는 10진 정수 %f float ☞ 16진 실수 %x hex ☞ 16진수 소문자 %X hex ☞ 16진수 대문자 %p pointer ☞ 4B 16진수 대문자 %c character ☞ 문자 1개 출력 %s string ☞ 문자열 출력 포인터
Visual C++ 에서 C4996 에러 처리 막는 법 Visual C++ 컴파일러에서 발생하는 에러 중 ... (중간 생략) ... error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. ... (중간 생략) ... scanf 함수가 보안이 취약하므로 ☞ scanf_s 함수를 대신 사용하라고 에러 처리한 것임 fopen 함수 ☞ fopen_s 함수 등도 마찬가지 경우 해결책 ... 이를 무시하고 일반적인 scanf, fopen 함수 등을 그대로 사용하려면 앞에서 영문 에러 메시지의 안내에 표시한대로 소스 맨 위에 다음 한 줄을 추가 #define _CRT_SECURE_NO_WARNINGS
memcpy() 함수를 사용하는 예제들 memcpy() 함수는 변수를 메모리에 저장하고 비트를 읽어오는 것으로 다음 조건 하에서 정상 동작함 인텔 CPU일 것 자료형 선언에서 32비트 int, float 등 정수나 실수의 비트 수가 CPU마다 다를 수 있기 때문 엔디언 방식이 CPU마다 다를 수 있기 때문 엔디언 ☞ 메모리에 변수를 저장하는 방식 (5장 참조) 윈도우 운영체제일 것 <windows.h> 헤더 파일에 포함
진수 변환 & IEEE 754 표준 3장 관련 C 언어 프로그래밍 실습
C 언어실습 문제 1~6 실습 1 ☞ 양의 정수 10진 > 2진 변환 재귀 함수 이용 실습 2 ☞ 양의 10비트 정수 10진 > 2진 변환 pow()와 atoi() 함수 이용 실습 3 ☞ 32비트 정수 10진 > 2진 변환 실습 4 ☞ 8비트 정수 10진 > 2진 변환 실습 5 ☞ 8비트 정수 2진 > 10진 변환 pow() 함수 이용 실습 6 ☞ IEEE 754 표준 부동소수점 형식 실습 3, 4, 6 ☞ memcpy() 함수 이용
C 언어실습 문제 1 재귀 함수를 이용해 다음과 같이 양의 정수를 10진수에서 2진수로 변환하는 프로그램을 작성하라. 몇 가지 10진수를 입력해 실행 결과를 확인하라. (ex.) 1101(2) = 23+22+20 = 13 재귀 함수(recursive function)란? 혹은 순환 함수 함수 안에서 다시 자기 자신을 호출하는 함수 이런 동작 ☞ 재귀 호출(recursive call) 반복문 형태를 간단하게 해결
★실습 1 ☞ 양의 정수 10진 > 2진 변환 #define _CRT_SECURE_NO_WARNINGS 입력 후 결과 확인 ★실습 1 ☞ 양의 정수 10진 > 2진 변환 13 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void bin(int n); int main() { int n; printf("양의 정수 10진 > 2진 변환 \n\n"); printf("10진수 입력 : "); scanf("%d", &n); printf(" 2진수 변환 : "); if (n>=0) bin(n); else printf("양의 10진 정수를 입력하라!"); printf("\n\n"); return 0; } void bin(int n) { if (n >= 2) { bin(n / 2); printf("%d", n % 2); else printf("%d", n % 2); 음수이면 경고 함수 선언 함수 정의 ① 재귀 호출로 몫을 먼저 계산 ③ 나머지는 나중에 출력 함수 호출 ② 최종 결과 몫을 먼저 출력
☞ 13 > 1101(2) 변환 ★실습 1 ☞ 설명 함수호출 몫 계산 나머지 출력 n=13 n/2=6 n % 2 = 1 ③ 나머지는 나중에 출력 n=6 n/2=3 n % 2 = 0 ① 재귀 호출로 몫을 먼저 계산 함수호출 몫 계산 나머지 출력 n=3 n/2=1 n % 2 = 1 ② 최종 결과 몫을 먼저 출력 n % 2 = 1
C 언어실습 문제 2 pow() 와 atoi() 함수를 이용해 다음과 같이 양의 10비트 정수를 10진수에서 2진수로 변환하는 프로그램을 작성하라. 몇 가지 10진수를 입력해 실행 결과를 확인하라. (ex.) 1100110011(2) = 29+28+25+24+21+20 = 819 재귀 함수를 사용하지 말 것 atoi(아스키 문자열) ☞ 10글자까지 숫자로 변환 pow(x, y) ☞ x의 y승 (x, y는 double) ASCII to integer power
★실습 2 ☞ 양의 10비트 정수 10진 > 2진 #define _CRT_SECURE_NO_WARNINGS 입력 후 결과 확인 ★실습 2 ☞ 양의 10비트 정수 10진 > 2진 819 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int i, n, k; char bit[10]; restart: printf("양의 10비트 정수 10진 > 2진 변환 \n"); printf("10진수 입력 : " ); scanf("%d", &n); printf(" 2진수 변환 : " ); if (n<0 || n>1023) { printf("0 부터 +1023 사이 10진수를 입력하라! \n\n"); goto restart; } for (i=0; i<=9; i++) { k = pow(2.0,9-i); if (n/k) { bit[i] = '1'; n = n - k; } else bit[i] = '0'; } printf("%d", atoi(bit)); printf("\n\n"); atoi( ) pow(x,y) 29~20 10bit를 문자로 저장 문자 10자까지 숫자로 변환
C 언어실습 문제 3 memcpy() 함수를 이용해 다음과 같이 2의 보수로 표현되는 32비트 정수를 10진수에서 16진수 및 2진수로 변환하는 프로그램을 작성하라. (ex.) 0111 0111(2) = 26+25+24+22+21+20 = 119 3장 연습문제 52~53번 풀이와 비교해 검증하라. memcpy() 함수 memcpy(도착 주소, 출발 주소, 바이트 수) 메모리에 저장된 변수를 다른 주소에 복사 memory copy
★실습 3 ☞ 32비트 정수 10진 > 2진 변환 #define _CRT_SECURE_NO_WARNINGS 입력 후 결과 확인 ★실습 3 ☞ 32비트 정수 10진 > 2진 변환 119 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> int main() { int src; unsigned des; int i; char bit[32]; printf("(2의 보수) 32비트 정수 10진 > 16 및 2진 변환 \n"); printf("10진수 입력 : " ); scanf("%d", &src); memcpy(&des, &src, 4); printf("16진수 변환 : %x \n", des); printf(" 2진수 변환 : "); for (i=0; i<=31; i++) { if (des & 0x80000000) bit[i] = '1'; else bit[i] = '0'; if (i!=0 && i%4==0) printf(" "); printf("%c", bit[i]); des <<= 1; } printf("\n\n"); memcpy() 1비트씩 밀어 MSB로 1/0 판단 4비트씩 끊어 읽기 des = des<<1 src 변수 저장 주소에서 4B 복사해 des에 저장
★실습 3 ☞ 활용 3장 연습문제 52~53번 풀이 비교 52 53
C 언어실습 문제 4 memcpy() 함수를 이용해 다음과 같이 2의 보수로 표현되는 8비트 정수를 10진수에서 16진수 및 2진수로 변환하는 프로그램을 작성하라. 실습 3 예제를 약간 수정해 쉽게 만들 수 있다. memcpy()로 4B를 읽은 32비트 예제와 동일하나 인텔 x86 계열 CPU는 대개 8bit 정수형 자료형이 없어 short (16bits)나 int, long (32bits)을 대신 사용 하위 1B만 선택하도록 -128 ~+127 입력만 허용할 것
★실습 4 ☞ 8비트 정수 10진 > 2진 변환 입력 후 결과 확인 ★실습 3 ☞ 수정 119 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> int main() { int src; unsigned des; int i; char bit[8]; restart: printf("(2의 보수) 8비트 정수 10진 > 16 및 2진 변환 \n"); printf("10진수 입력 : " ); scanf("%d", &src); memcpy(&des, &src, 4); if (src<-128 || src>127) { printf("-128 부터 +127 사이 10진수를 입력하라! \n\n"); goto restart; } des = des & 0xFF; printf("16진수 변환 : %x \n", des); printf(" 2진수 변환 : "); for (i=0; i<=7; i++) { if (des & 0x80) bit[i] = '1'; else bit[i] = '0'; if (i!=0 && i%4==0) printf(" "); printf("%c", bit[i]); des <<= 1; printf("\n\n"); 32비트 중 하위 8비트만 선택 보라 부분 ☞ 추가 파란 부분 ☞ 수정
★실습 4 ☞ 활용 3장 연습문제 52~53번 풀이 비교 52 53
C 언어실습 문제 5 pow() 함수를 이용해 다음과 같이 2의 보수로 표현되는 8비트 정수를 2진수에서 10진수로 변환하는 프로그램을 작성하라. 몇 가지 10진수를 입력해 실행 결과를 확인하라. (ex.) 01010101(2) = 26+24+22+20 = 85 3장 연습문제 52~53번 풀이와 비교해 검증하라.
★실습 5 ☞ 8비트 정수 2진 > 10진 변환 #define _CRT_SECURE_NO_WARNINGS 입력 후 결과 확인 ★실습 5 ☞ 8비트 정수 2진 > 10진 변환 01010101 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> int main() { int i, dec; char bit[8], str[9]; restart: printf("(2의 보수) 8비트 정수 2진 > 10진 변환 \n"); printf(" 2진수 입력 : " ); gets(str); for (i=0; i<=7; i++) { if (str[i]=='1') bit[i] = 1; else if (str[i]=='0') bit[i] = 0; else { printf("8비트 2진수를 입력하라! \n\n"); goto restart; } } if (bit[0]) dec = -128; else dec = 0; for (i=1; i<=7; i++) { dec += bit[i]*pow(2.0,7-i); } printf("10진수 변환 : %d \n\n", dec ); 1, 0 이외의 입력은 음수이면 양수이면 문자열 입력함수 str[9] 배열 크기 ☞ 문자열 + 끝 표시 null(\0) 문자 포함
★실습 5 ☞ 활용 3장 연습문제 52~53번 풀이 비교 52 53
C 언어실습 문제 6 10진 실수 값을 IEEE 754 표준의 32비트 2진 부동소수점 형식으로 구하는 프로그램을 작성하라. 위의 형식으로 출력되도록 프로그램을 작성하라. 32비트 형식의 16진수 표현 32비트 형식의 2진수 표현 (4비트씩 끊어 읽기) 부호(1)-지수(8)-가수(23) 비트로 구분해 표현 실습 3 예제를 수정해 만들 수 있다. 3장 연습문제 62~64번 풀이와 비교해 검증하라.
★실습 6 ☞ IEEE 754 표준 부동소수점 형식 입력 후 결과 확인 ★실습 3 ☞ 수정 -69.3 ☞ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> int main() { float src; unsigned des; int i; char bit[32]; printf("IEEE 754 표준 32비트 2진 부동소수점 형식 \n"); printf("10진수 실수 입력 : " ); scanf("%f", &src); memcpy(&des, &src, 4); printf("32비트 형식 (16진수) : %x \n", des); printf("32비트 형식 ( 2진수) : "); for (i=0; i<=31; i++) { if (des & 0x80000000) bit[i] = '1'; else bit[i] = '0'; if (i!=0 && i%4==0) printf(" "); printf("%c", bit[i]); des <<= 1; } printf("\n"); printf("부호(1)-지수(8)-가수(23) : "); for (i=0;i<=31;i++) { if ((i==1)||(i==9)) printf("-"); printf("%c", bit[i]); } printf("\n\n"); } 정수형 대신 실수형 입력 변수 4B 복사 부호-지수-가수부 영역 구분 추가
★실습 6 ☞ 활용 3장 연습문제 62~64번 풀이 비교 62 63 64
- End -