5.1 반복 루프와의 첫 만남
goto문은 실제 문법으로 잘 쓰이지 않음, 단종된 기술임
#include <stdio.h>
int main()
{
int n = 1;
label:
printf("%d\n", n);
n = n + 1;
if (n == 10) goto out;
goto label;
out:
return 0;
}
5.2 대입 연산자와 몇 가지 용어들
Data object: **메모리에 공간**을 차지하고 있는 데이터들의 형태(이 개념이 객체지향으로 발달)
L-value(object locator value): 메모리 공간을 대표하는 변수명
R-value(value of an expression): 숫자,계산 값
i = 1024;
L-value(i)는 어떤 메모리 공간을 의미하므로 Data object다
R-value(1024)는 상수(literal)이므로 Data object가 아니다
L-value는 임시적으로 R-value 역할을 할 수 있음(i = i + 1)
a+b를 더한 값 자체는 L-value가 아닌 R-value이다. (사용한 후에는 사라지는 값이므로)
5.3 더하기, 빼기, 부호 연산자들
5.4 곱하기 연산자
/*
* 복리 계산 문제
*/
#include <stdio.h>
int main()
{
double seed_money, target_money, annual_interest;
printf("Input seed money : ");
scanf("%lf", &seed_money);
printf("Input target money : ");
scanf("%lf", &target_money);
printf("Input annual interest(%%) : ");
scanf("%lf", &annual_interest);
double fund = seed_money;
int year_count = 0;
while (fund < target_money)
{
fund += (fund * annual_interest / 100);
year_count++;
printf("%lf\n", fund);
}
printf("It takes %d years\n", year_count);
return 0;
}
5.5 나누기 연산자
printf("%d\n", 7 / 2); // 3 // 3.5에서 버림, 컴퓨터는 반올림 해주지 x
printf("%d\n", -7 / 2); // -3 // Truncating toward zero(C99) 0에 가까운쪽으로 절삭
printf("%f\n", 9.0 / 4); // 2.250000 // 컴파일러가 4를 내부적으로 double로 변경
5.6 연산자 우선순위와 표현식 트리
컴파일러가 내부적으로 그래프 구조를 만든 다음 우선순위에 맞춰 계산하는 방식
#include <stdio.h>
int main()
{
int seconds = 0, minutes = 0, hours = 0;
printf("Input seconds : "); // while문 조건 성립위해 입력 밖에서 한번 실행
scanf("%d", &seconds);
//TODO: seconds -> hours, minutes, seconds
while (seconds >= 0)
{
minutes = seconds / 60;
seconds %= 60;
hours = minutes / 60;
minutes %= 60;
// print result
printf("%d hours, %d minutes, %d seconds\n", hours, minutes, seconds);
printf("Input seconds : "); // 이곳에 입력을 해야 마지막값에서 음수입력시 출력없이 바로 조건문으로 들어감
scanf("%d", &seconds);
}
printf("Good bye\n");
/*
* 음수를 나눌경우엔 어떻게 되는가.
* '%' 연산자에서 '앞'에있는 피연산자(operand)가 음수면 음수값으로 출력.
*/
int div, mod;
div = 11 / 5;
mod = 11 % 5;
printf("div = %d, mod = %d\n", div, mod); // div = 2, mod = 1
div = 11 / -5;
mod = 11 % -5;
printf("div = %d, mod = %d\n", div, mod); // div = -2, mod = 1
div = -11 / -5;
mod = -11 % -5;
printf("div = %d, mod = %d\n", div, mod); // div = 2, mod = -1
div = -11 / 5;
mod = -11 % 5;
printf("div = %d, mod = %d\n", div, mod); // div = -2, mod = -1
}
5.8 증가, 감소 연산자
#include <stdio.h>
int main()
{
int count = 0;
// ++count or count++
while (count < 10)
{
printf("%d ", count++); // 0 1 2 3 4 5 6 7 8 9 // 사용이 끝난 후 증가, 예약하여 증가하는 형태
}
printf("\n");
count = 0;
while (count < 10)
{
printf("%d ", ++count); // 1 2 3 4 5 6 7 8 9 10 // 증가한 상태로 사용
}
printf("\n");
int i = 1, j = 1;
int i_post, pre_j;
/**************************************************
i_post = i++;
pre_j = ++j;
printf("%d %d\n", i, j); // 1 1 // Line 25, 26에서 증가됬지만 R-value값이므로 본래 변수에는 영향x
printf("%d %d\n", i_post, pre_j); // 1 2 // i_post는 증가하기 전의 값 출력
/**************************************************
/* ++ and -- affect modifiable l-values */
int x = 1, y = 1, z;
z = x * y++; // (x) * (y++), not (x*y)++
z = (x * y)++; // error (x * y) 는 수정가능한 l-values가 아닌 r-values 이기 때문에 error
z = 3++; // error 상수에 대해서도 l-values가 아니기때문에 error
/**************************************************
/* Bad practices*/
int n = 1;
printf("%d %d", n, n * n++); // 증감 연사자를 사용한 변수를 여러번 사용될 경우 시스템마다 결과가 다르게 나올 수 있다
int x = n / 2 + 5 * (1 + n++);
int y = n++ + n++; // 눈으로 보기에 헷갈리고 의도가 뭔지 알기 힘들다
return 0;
}
5.9 표현식과 문장 expressions and statements
표현식(Expressions): 여러가지 연산자와 피연산자가 조합되어 있는 수식
문장(statements): 규칙을 따르는 진술
주효과는 값을 계산하는 것이고, 변수에 대입은 부차적인것(side-effect)
/**************************************************
Sequence Points(;): 값을 언제 계산하는가?
/**************************************************
while문의 조건문 같은 경우는 Sequence Points(;)가 없어도 조건문 계산이 되는 완전한 표현식
컴파일러 입장에서 ++를 괄호 밖에서 계산할지, 세미클론에서 계산을 할지 모호
5.10 순서도 flowchart
5.11 자료형 변환 type conversion
형변환은 중,고급 프로그래머로 갈수록 주의해야한다!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
/* promotions(승진) in assignments*/
short s = 64;
int i = s;
//short가 int보다 작다. 작은걸 큰거에 대입해줄때는 문제가 안된다.
float f = 3.14f;
double d = f;
/*demotion in assignments*/
//큰 자료형(double)을 더 작은쪽(float)에 넣으려고 시도하는것을 demotion이라고 한다.
// truncation from 'double' to 'float'
// truncation 절삭.
d = 1.25;
f = 1.25; // 1.25f라고 안썼기때문에 double이다.
//얘는 왜 warning이 안뜰까? 1.25같은 숫자는
//double이던 float이던 정밀하게 표현할 수 있다. 1/2^2이기 때문.(2의거듭제곱으로 나누기 가능하기 때문)
f = 1.123;
// double일때의 1.123이랑 float일때의 1.123이랑 미묘하게 다르기때문.
// f = 1.123f;라고 치면 문제 없음.
/*ranking of types in operations*/
// long double > double > float (정수형은 실수형보다 랭킹이 낮다)
// (정수를 실수와 연산하고자하면 정수를 실수로 형변환 한다음에 연산해야한다)
// (정수간의 랭킹은 조금 덜 중요하지만 중요함, 밑에 같은 줄에 있는 것들은 랭킹이 같다)
// unsigned long long, long long
// unsigned long, long
// unsigned long, long
// unsigned, int
// short int, unsigned short int
// signed char, char, unsigned char
// _Bool
d = f + 1.234; // cpu는 서로 다른 자료형을 연산 못함. f를 double로 바꿔주고 계산.
f = f + 1.234; // 'possilbe lost data.' double을 float에 넣으려고해서 문제.
/* automatic promotion of function arguments*/
//자동적으로 이뤄지는 promotion, 함수의 arguments에 적용되는 것.
// 크게 신경안써도 되는 측면. 위 규칙에 따라 이뤄지는게 대부분.
// 그렇지 않은 경우가 아래 2경우.
// 1. Functions without prototypes
// 2. Variadic functions (printf같은 경우 - 인자가 변할 수 있는경우)
// 2번은 고급프로그래밍하는 경우. ellipsis.
/* casting operators*/
// 위에서는 컴파일러가 알아서 형변환 해주는 경우이고,
// 이경우는 우리가 형변환을 할거다. 의도적으로 표현하는 경우.
// casting operator를 사용해서 표기해주는게 좋음. (double), (int)...
// C++가면 달라지는데, 관습적으로 C스타일의 casting operator도 많이 쓴다.
d = (double)3.14f;
// 3.14f는 float인데, (double)을 해주면 expression의 값이 double이 된다.
i = 1.6 + 1.7; // double을 i(integer)에 대입해주면 절삭된다.
i = (int)1.6 + (int)1.7; // 실수를 int로 형변환.
// 첫번쨰 같은 경우 1.6 +1.7 = 3.3인데 절삭되서 3
// 두번째 같은 경우 1+1 이 되서 2.
/*more examples*/
char c;
//int i;
//float f;
f = i = c = 'A'; // 65
// int to float. data size는 같은데 유효숫자 갯수가 다르다.
// char - int( promotion )
// int - float (형변환)
printf("%c %d %f\n", c, i, f); // A 65 65.000000
c = c + 2; // 'C', 67
i = f + 2 * c; // 65.0f + 2*67
// float(f)와 2*c(int)를 계산하려니 int를 float으로 만들어주고 계산을 하는데,
// float값을 int(i)에 대입해주려니 자료형이 다르니 truncation해서 넣는다.
// 그래서 데이터 손실될 수있다.
printf("%c %d %f \n", c, i, f); // C 199 65.000000
c = 1106; // demolition, 1106 = 0b10001010010 -> 0b01010010(char는 1바이트이므로 앞부분 짤림) = 1106 % 256(앞부분을 자르는게 나머지 연산자를 적용하는것과 결과가 같음) = 82 = 'R'
// 1106 - int , char보다 높은 범위의 수 . 그래서 강등당해서 들어감.
// 100이 truncation되고, 0b01010010이 남아서 이게 10진수로 82. 그게 'R'임.
// 비트연산자는 나중에 나온다.
printf("%c\n", c); // R
c = 83.99;
// 84가 나오는게 아니라, 83이 나오고 이게 'S'이다.
printf("%c\n", c); // S
return 0;
}
5.12 함수의 인수와 매개변수
#include <stdio.h>
void draw(int n); // ANSI function prototype declaration
int main()
{
int i = 5;
char c = '#'; // 35
float f = 7.1f;
draw(i);
//draw(c);
//draw(f); // float 자료형을 매개변수 자료형이 int인 함수에 넣으려고해 'possible loss of data' 경고
// 권장하는 방식
draw((int)c);
draw((int)f);
/* Arguments(인수) vs. Parameters(매개변수)*/
// actual argument, actual parameter -> argument (values): 함수를 '호출'하는 측면
// formal argument, forma parameter -> parameter (variables): 함수를 '정의'하는 측면
return 0;
}
void draw(int n)
{
//while(n > 0)
//{
// printf("*");
// n--;
//}
while (n-- > 0)
printf("*");
printf("\n");
}
'Programming > C' 카테고리의 다른 글
[따배씨] 섹션 4. 문자열과 형식 맞춘 입출력 (0) | 2020.07.21 |
---|---|
[따배씨] 섹션 3. 데이터와 C언어 (0) | 2020.07.16 |
[따배씨] 섹션 2. C언어 소개 (0) | 2020.07.16 |
[따배씨] 섹션 1. 천천히 시작해봅시다 (0) | 2020.07.16 |
[따배씨] 섹션 0. 초보 프로그래머를 위한 컴퓨터의 작동원리 (0) | 2020.07.16 |
댓글