1. 복합문(블록)
* 복합문(Compound Statement)
- 두 개 또는 그 이상의 문장들이 중괄호( { } )로 묶여 있는 것을 말한다. 이것을 블록(block)이라고 부른다.
2. 데어터형 변환
** 올림 변환 (Promotion)
- char형과 short형이 (signed와 unsigned 모두) 하나의 표현식에 나타나면, 자동으로 int형으로, 필요하면 unsigned int형으로 변환된다.
(short형과 int형의 크기가 같다면, unsigned short형은 int형으로 변환된다.)
- 두 가지 데이터형이 사용된 어떤 연산에서, 두 값은 두 가지 데이터형 중 더 높은 등급으로 변환된다.
*** 데이터형 높은등급 나열
낮음 -> 높음
int < unsigned int < long < unsigned long < long long < unsigned long long < float < double < long double
(예외, long형과 int형의 크기가 같을 때에는 unsigned int형이 long형보다 등급이 높다.)
** 내림 변환(Demotion)
- 대입문에서 최종 계산 결과는 그 값이 대입될 변수의 데이터형으로 변환된다.
- 문제점 : 낮은 등급의 데이터형은 완전한 수를 저장하느데 크기가 충분하지 않을 수 있다.
즉, 8비트 char형 변수는 정수 101은 저장할 수 있지만, 정수 22334는 저장하지 못한다.
- 부동소수점형이 정수형으로 내림 변환 될 때, 버림 또는 0을 향하여 버림이 일어난다. 따라서 23.12와 23.99가 둘 다 버림에 의해 23이 되고, -23.5가 -23이 된다는 것을 의미한다.
** 무시(Override)
- 함수의 전달인자로 전달될 때, char형과 short형은 int형으로 변환되고, float형은 double형으로 변환된다.
/* 자동데이터형 변환*/
#include <stdio.h>
int main(void)
{
char ch;
int i;
float fl;
fl = i = ch = 'C'; /* line 9 */
printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); /* line 10 */
ch = ch + 1; /* line 11 */
i = fl + 2 * ch; /* line 12 */
fl = 2.0 * ch + i; /* line 13 */
printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); /* line 14 */
ch = 1107; /* line 15 */
printf("Now ch = %c\n", ch); /* line 16 */
ch = 80.89; /* line 17 */
printf("Now ch = %c\n", ch); /* line 18 */
return 0;
}
- 라인 9 - 10 : 문자 'C'가 ch에 1바이트 ASCII 값으로 저장된다. 정수형 변수i는 'C'의 정수형 변환값을 받는다.
즉, 67이 4바이트로 저장된다.마지막으로 fl은 67의 부동소수점형 변환값 67.00을 받는다.
- 라인 11,14 : 문자 변수 ch의 값이 정수 67로 변환된다. 그것이 1이 더해진다. 결과로 얻어진 4바이트 정수68이
1바이트로 잘려 ch에 저장된다. %c 지정자를 사용하여 출력할 때, 68은 'D'에 해당하는 ASCII 코드로 해석된다.
- 라인 12,14 : ch값이 2와의 곱셈을 위해 4바이트 정수(68)로 변환된다. 결과로 얻어지는 정수(136)가 fl과의 덧셈을 위해
부동소수 점 형으로 변환된다. 결과(203.00f)가 int형으로 변환되어 i에 저장된다.
- 라인 13,14 : ch의 값 ('D' 또는 68)이 2.0과의 곱셈을 위해 부동소수점 형으로 변환된다.
i의 값(203)이 덧셈을 위해 부동소수점형으로 변환된다. 결과 (339.00)가 fl에 저장된다.
- 라인 15,16 : ch에 다소 큰 수를 설정하여 내림 변환이 일어나는 예를 보여준다. ch는 s문자에 해당하는 ASCII 코드값을 얻는다.
즉, 좀더 정확히 말하면, 1107 % 256 = 83이 S에대한 코드이다.
- 라인 17,18 : 내림변환(Demotion)의 다른경우를 해보는 예제이다.
ch는 부동소수점 수와 같게 설정된다. 버림이 발생된 후에 ch는 ASCII코드로 마무리 짓는다.
3. 캐스트 연산자 (Cast Operator)
- 사용자가 원하는 (또는 데이터형이 변환되는 사실을 사용자가 알고있는)정확한 데이터형으로 변환하도록 사용자가 요구할 수 있다.
- 원하는 데이터형 이름을 괄호 안에 넣고, 그것을 변환할 변수 이름 앞에 위치시키면된다.
ex.)
mice = 1.6 + 1.7; / 결과값 : 3.3 -> int형 변수에는 3으로 대입된다.
mice = (int) 1.6 + (int) 1.7; / 결과값 : 1.6 , 1.7 -> 1로 변환된다. 1 + 1이므로 mice에 2가 대입된다.
4. 전달인자를 사용하는 함수
*** 전달인자 선언하면
- 형식전달인자 (Formal argument) 또는 형식매개변수 (Formal Parameter) 변수가 만들어진다.
** butler() 함수
- 전달인자를 사용하지 않는 함수
- 리턴값을 가지지 않는다.
//* 하나의 파일에서 두개의 함수를 사용하는 프로그램*/
#include <stdio.h>
void butler(void); /* ANSI/ISO C 함수 프로토타입 */
int main(void)
{
printf("butler 함수 밖에 있느냐?\n");
butler();
printf("그래. 차 한 잔 내오고, DVD도 가져와줘.\n");
return 0;
}
void butler(void) /* 함수 정의의 시작*/
{
printf("부르셨습니까? 주인님!\n");
}
- void : "비어있다" 라는 뜻
- butler() 가 자기 할 일을 끝냈을 때, 프로그램은 main()에 있는 그 다음 문장으로 제어를 넘긴다.
- butler() 가 정의된 위치가 아니라, main()에서 butler()가 호출되는 위치가 butler()함수의 실행 시기를 결정한다.
- 즉, 첫번째 printf() 함수가 실행되고, 이어서 butler()함수가 실행된 후 , 두번째 printf() 함수가 실행될 것이다.
** pound()
- 파운드 기호(#)를 지정된 개수 만큼 출력
- 리턴값이 없다.
- pound(int n) : 하나의 전달인자를 사용한다. int 값이다.
** n (매개변수) / times(전달인자)
** 프로토타입(Prototype) : 함수의 리턴값과 전달인자를 기술하는 함수의 선언
/* 하나의 전달인자를 사용하는 함수를 정의한다. */
#include <stdio.h>
void pound(int n); // ANSI 프로토 타입
int main(void)
{
int times = 5;
char ch = '!'; // ASCII 코드값이 33이다.
float f = 6.0f;
pound(times); // int 전달인자
pound(ch); // pound((int)ch); 와 같다
pound(f); // pound((int)f); 와 같다 '실행되지만 정확하게 행동하지는않을것이다..?'
// f의 값이 너무 커서 int형에 맞지 않는다면 도움이 되지않는다 ㅎㅎㅎㅎㅎ
return 0;
}
void pound(int n) // ANSI 스타일의 함수 헤더가
{ // 하나의 int형 전달인자를 사용한다고 알려준다.
while (n-- > 0)
printf("#");
printf("\n");
}
- void pound(int n) : 이 함수가 전달인자를 사용하지 않는다면, 함수 머리의 괄호 안에 키워드 void가 들어갈것이다.
그러나 이 함수가 하나의 int형 전달자를 사용하기 때문에, 그 괄호 안에 int형 변수의 선언이 들어있다.
- int형 n 변수 : 형식 매개변수이다.
pound(10)과 같이 함수를 호출하면, n에 값 10이 대입된다.
- pound(times) : times의 값 5를 n에 대입한다.
이것을 함수 호출이 함수에 값을 전달한다고 말한다.
(실전달인자 (Actual Argument) 또는 실매개변수(Actual Parameter)라고 부른다.)
ex.) pound(10) 은 실전달인자 10을 함수에 전달한다. 그 10은 형식매개변수(변수n)에 대입된다.
즉, main()에 있는 times 변수의 값이 pound()에 있는 새로운 변수 n에 복사된다.
- pound(ch) : ch는 char형이다. 그것은 문자 !로 초기화 되어있다. 그러나 char형은 pound()함수에 대한 틀린 데이터 형이다.
자동으로 데이터형 캐스트(TypeCast)를 int 전달인자로 변환해서 ch전달인자에 적용한다.
- pound(f) : 이 전달인자를 위한 적절한 데이터 형에 대해 float형 변수 f로 변환하기 위해 cast형을 만들어낸다.
- 실행결과 : pound()함수는 5개의 파운드 기호(#)와 하나의 개행(\n 줄바꿈)을 출력한다.
** ANSI C란?
- C언어가 ANSI C로 표준화 되면서 함수의 호출 시에 오류를 예방하기 위해 모든 함수는 호출 전에 함수의 형명, 함수명, 인자를 선어하는 것을 원칙으로 하게 되었다.
- 열거형(Enum)과 void형 같은 새로운 자료형을 추가됐다.
- 기존 C의 표준 라이브러리 함수의 정의를 구체적으로 정의하고 표준 헤더파일도 구체화 됐다.
- 선행처리 기능을 강화 하였으며 #elif, #error, #pragma등이 추가 됐다.
- 기존 C 구조체는 포인터로만 대입되고, 함수의 인수 및 반환이 불가능하였지만 ANSI C에서는 직접 대입 및 함수의 인수와 반환이 가능해졌다.
- Const, Signed, Volatile과 같은 수식자가 추가됐다.
- 기존 C에서는 float형은 연산 시 자동으로 double형으로 변환되었지만 ANSI C에서는 변환이 필요 없으면 float 자체로 연산이 수행된다.
- 변수명과 함수명의 식별자의 유효길이가 8 -> 31문자로 변경되었습니다. 즉, 기존에는 변수명이나 함수명이 8자 이상되더라도 9번째 문자부터는 무시하고 8자리까지만 이름으로 인식됐다.
5. 예제 프로그램 (5.16)
// 육상선수에게 유용한 프로그램
#include <stdio.h>
const int S_PER_M = 60; // 1분의 초 수
const int S_PER_H = 3600; // 1시간의 초 수
const double M_PER_K = 0.62137; // 1킬로미터의 마일 수
int main(void)
{
double distk, distm; // 달린거리(각각 킬로미터 수와 마일 수)
double rate; // 평균속도 (mph; 시간당 마일 수로)
int min, sec; // 달린 시간(분 과 초 수로)
int time; // 달린 시간(초 수로만)
double mtime; // 1마일을 달린 시간(초 수로만)
int mmin, msec; // 1마일을 달린 시간 (분 과 초 수로만)
printf("이 프로그램은 미터단위계로 측정한 달리기 기록을\n");
printf("1마일을 달린 시간과, 평균속도(mph)로 변환한다.\n");
printf("달린 거리를 킬로미터(km)수로 입력하세요.\n");
scanf("%lf", &distk); // double형을 위하여 %lf 사용
printf("달린 시간을 분 수와 초 수로 입력하세요.\n");
printf("먼저 분 수부터 입력하세요.\n");
scanf("%d", &min);
printf("이제 초 수를 입력하세요.\n");
scanf("%d", &sec);
// 달린 시간을 초 수로 변환한다.
time = S_PER_M * min + sec;
// 킬로미터 수를 마일 수로 변환한다.
distm = M_PER_K * distk;
// 초당 마일 수 * 시간당 초 =mph
rate = distm / time * S_PER_H;
// 시간 / 거리 = 마일당 시간
mtime = (double) time / distm;
mmin = (int) mtime / S_PER_M; // 분 을 구한다.
msec = (int) mtime % S_PER_M; // 나머지 초 수를 구한다.
printf("당신은 %1.2f km (%1.2f miles)를 %d 분, %d 초에 달렸다.\n",
distk, distm, min, sec);
printf("이 페이스는 1마일을 %d 분, %d 초에 달린것으로 나온다.\n", mmin,msec);
printf("평균 속도는 %1.2f mph 였다.\n",rate);
return 0;
}
- mtime , mmin, msec 변환부분은 명시적으로 표시하기 위해 cast연산자를 사용했다.
'LAB > C' 카테고리의 다른 글
[24.08.08] c언어의 기초6 (1) | 2024.08.08 |
---|---|
[24.08.08] c언어의 기초5(2) (0) | 2024.08.08 |
[24.08.07] c언어의 기초4 (0) | 2024.08.07 |
[24.08.07] C언어의 기초3 (0) | 2024.08.07 |
[24.08.06] C언어의 기초2 (0) | 2024.08.07 |