if
제어 표현식 수정#include <stdio.h>
#include <stdlib.h>
int main(void)
{
double A[5] = {
[0] = 9.0,
[1] = 2.9,
[4] = 3.E+25,
[3] = .00007,
};
for (size_t i = 0; i < 5; i++) {
if (A[i] > 5.0) {
printf("element %zu is %g, \tits square is %g\n",
i,
A[i],
A[i] * A[i]
);
}
}
return EXIT_SUCCESS;
}
size_t i = 0;
일때 i--;
를 수행하면?#include <stdio.h>
#include <stdint.h>
int calc_bits(size_t value)
{
int nbits = 0;
while (value > 0)
nbits++, value >>= 1;
return nbits;
}
int main(void)
{
printf("calc_bits(SIZE_MAX): %d\n", calc_bits(SIZE_MAX));
printf("(size_t) 0 - 1: %zu\n", (size_t) 0 - 1);
return 0;
}
size_t
는 unsigned
자료형이므로 그 값이 0 이하가 되면 integer overflow
가 발생하게 된다. 더 정확하게 표준에 의거하면 unsigned integer
에 대한 overflow
는 존재하지 않고 well-defined behavior
인 rules of modular arithmetic modulo 이 수행된다.
따라서 그 결과는 ( 은 오브젝트를 표현하기 위해 사용된 비트 수) 이 된다. 필자의 컴퓨터는 n
이 64 이므로 결과는 인 () 가 된다.
printf
문을 추가하여 분석#include <stdio.h>
#include <stdlib.h>
static double const eps1m01 = 1.0 - 0x1P-01;
static double const eps1p01 = 1.0 + 0x1P-01;
static double const eps1m24 = 1.0 - 0x1P-24;
static double const eps1p24 = 1.0 + 0x1P-24;
int main(int argc, char *argv[argc + 1])
{
for (int i = 1; i < argc; ++i) {
double const a = strtod(argv[i], 0);
double x = 1.0;
printf("target number: %g\n", a);
for (;;) {
double prod = a * x;
if (prod < eps1m01) {
x *= 2.0;
} else if (eps1p01 < prod) {
x *= 0.5;
} else {
break;
}
printf("x = %.12f\n", x);
}
for (;;) {
double prod = a * x;
if ((prod < eps1m24) || (eps1p24 < prod))
x *= (2.0 - prod);
else
break;
printf("x = %.12f\n", x);
}
printf("heron: a=%.5e,\tx=%.5e,\ta*x=%.12f\n\n",
a, x, a*x);
}
return EXIT_SUCCESS;
}
argc
와 argv
의 사용 방법 argc
는 프로그램 실행 시 전달된 인자의 개수를 의미하며 argv
는 각각의 인자들을 가리키는 문자열이다. 예제 3-1
프로그램에서는 프로그램의 인자(argv
)로 실수를 전달받고 이를 헤론의 근사 공식에 대입하여 사용한다. 반복 횟수는 argc
를 통해 결정한다.
eps1m01
의 값을 화면에 출력하고 값을 바꿔보기#include <stdio.h>
#include <stdlib.h>
static double const eps1m05 = 1.0 - 0x1P-05;
static double const eps1p05 = 1.0 + 0x1P-05;
static double const eps1m24 = 1.0 - 0x1P-24;
static double const eps1p24 = 1.0 + 0x1P-24;
int main(int argc, char *argv[argc + 1])
{
printf("eps1m05: %f\n", eps1m05);
printf("eps1p05: %f\n", eps1m05);
for (int i = 1; i < argc; ++i) {
double const a = strtod(argv[i], 0);
double x = 1.0;
printf("target number: %g\n", a);
for (;;) {
double prod = a * x;
if (prod < eps1m05) {
x *= 2.0;
} else if (eps1p05 < prod) {
x *= 0.5;
} else {
break;
}
printf("x = %.12f\n", x);
}
for (;;) {
double prod = a * x;
if ((prod < eps1m24) || (eps1p24 < prod))
x *= (2.0 - prod);
else
break;
printf("x = %.12f\n", x);
}
printf("heron: a=%.5e,\tx=%.5e,\ta*x=%.12f\n\n",
a, x, a*x);
}
return EXIT_SUCCESS;
}
switch
문과 break
문 테스트#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[argc + 1])
{
char arg;
if (argc != 2) {
fprintf(stderr, "usage: %s <character>\n", argv[0]);
exit(EXIT_FAILURE);
} else {
arg = argv[1][0];
}
switch (arg) {
case 'm':
puts("this is a magpie");
break;
case 'r':
puts("this is a raven");
// break;
case 'j':
puts("this is a jay");
break;
case 'c':
puts("this is a chough");
break;
default:
puts("this is an unknown corvid");
}
return 0;
}
[책] 모던 C: 전문가를 위한 C 작성법! (옌스 구스테드 지음; 남기혁 옮김)