INT_MAX
DBL_MAX
/* | |
* 注释嵌套测试 | |
*/ | |
#include <stdio.h> | |
int main(int argc, char **argv) | |
{ | |
int i; | |
i = /*/*/0*/**/1; | |
printf("%d: %s\n", i, i? "支持嵌套注释": "不支持嵌套注释"); | |
/* | |
* 输出0表示不支持注释镶嵌。 | |
* 输出1表示支持注释镶嵌。 | |
*/ | |
return 0; | |
} |
/* | |
* 函数法计算日期到天数!! | |
*/ | |
#include <stdio.h> | |
int days(int y, int m, int d); | |
int main(int argc, char **argv) | |
{ | |
int i; | |
for (i = 2; i < 13; i++) | |
printf("%d\n", days(2015, i, 1)-days(2015, 1, 1)); | |
return 0; | |
} | |
/* | |
* 已3-1为一年开始来推算的 | |
*/ | |
int days(int y, int m, int d) | |
{ | |
m = (m+9)%12; | |
y = y - m/10; | |
return 365*y+y/4-y/100+y/400+(m*306+5)/10+(d-1); | |
} |
/* | |
* 达夫设备 | |
* 一种探索循环展开的程序 | |
*/ | |
#include <stdio.h> | |
#include <string.h> | |
#define TO_MAX 20 | |
#define FROM_MAX 20 | |
#define COUNT_MAX 20 | |
#define ARRAY_MAX 32 | |
void send(int *to, int *from, int count); | |
void print(int *to, int *from, int array_max); | |
int main(int argc, char **argv) | |
{ | |
int to[ARRAY_MAX], from[ARRAY_MAX], count; | |
int ito, ifrom, icount; | |
for(ito = 1; ito < TO_MAX; ito ++) | |
for(ifrom = 1; ifrom < FROM_MAX; ifrom ++) | |
for(icount = 1; icount < COUNT_MAX; icount ++) { | |
memset(to, 0x0, ARRAY_MAX * sizeof(int)); | |
memset(from, 0x0, ARRAY_MAX * sizeof(int)); | |
*to = ito; | |
*from = ifrom; | |
count = icount; | |
printf("to:%d\tfrom:%d\tcount:%d\n", ito, ifrom, count); | |
send(to, from, count); | |
print(to, from, ARRAY_MAX); | |
putchar('\n'); | |
} | |
return 0; | |
} | |
void send(int *to, int *from, int count) | |
{ | |
int n = (count + 7) / 8; | |
switch(count % 8) { | |
case 0: do { *to ++ = *from ++; | |
case 7: *to ++ = *from ++; | |
case 6: *to ++ = *from ++; | |
case 5: *to ++ = *from ++; | |
case 4: *to ++ = *from ++; | |
case 3: *to ++ = *from ++; | |
case 2: *to ++ = *from ++; | |
case 1: *to ++ = *from ++; | |
}while(-- n > 0); | |
} | |
} | |
void print(int *to, int *from, int array_max) | |
{ | |
int i; | |
for(i = 0; i < array_max; i ++) | |
printf("%d ", to[i]); | |
putchar('\n'); | |
for(i = 0; i < array_max; i ++) | |
printf("%d ", from[i]); | |
putchar('\n'); | |
} |
floor(sqrt(number)+0.5); | |
/* 避免浮点数误差 */ |
#include <stdio.h> | |
typedef void fun_t(int a); | |
typedef fun_t* recursion_t(int a); | |
/* NOTE maybe it is not portable */ | |
static fun_t *fun(int n) | |
{ | |
printf("run_fun: %d\n", n); | |
return (fun_t*)fun; | |
} | |
static void run_fun(int cnt) | |
{ | |
recursion_t *f = (recursion_t*)fun; | |
while (cnt--) { | |
f = (recursion_t*)f(cnt+1); | |
} | |
} | |
int main() | |
{ | |
printf("sizeof(void*): %d\n", sizeof(void*)); | |
printf("sizeof(fun_t*): %d\n", sizeof(fun_t*)); | |
printf("sizeof(fun): %d\n", sizeof(fun)); /* it is undefine behavior */ | |
printf("sizeof(run_fun): %d\n", sizeof(run_fun)); | |
printf("sizeof(void (*)()): %d\n", sizeof(void (*)())); | |
printf("org: %p ptr: %p\n", fun, fun(-1)); | |
int n; | |
scanf("%d", &n); | |
run_fun(n); | |
return 0; | |
} |
/* | |
* man or boy test | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
/* thunks */ | |
typedef struct arg { | |
int (*fn)(struct arg*); | |
int *k; | |
struct arg *x1, *x2, *x3, *x4, *x5; | |
}arg_t; | |
/* lambdas */ | |
int f_1(arg_t* _) { return -1; } | |
int f0(arg_t* _) { return 0; } | |
int f1(arg_t* _) { return 1; } | |
/* helper */ | |
/* TODO 预处理define语句的多参数?? */ | |
int eval(arg_t *a) { return a->fn(a); } | |
#define MAKE_ARG(...) (&(arg_t){__VA_ARGS__}) | |
#define FUN(...) MAKE_ARG(B, &k, __VA_ARGS__) | |
int A(arg_t*); | |
/* functions */ | |
int B(arg_t *a) | |
{ | |
int k = *a->k -= 1; | |
return A(FUN(a, a->x1, a->x2, a->x3, a->x4)); | |
} | |
int A(arg_t *a) | |
{ | |
return *a->k <= 0 ? eval(a->x4)+eval(a->x5) : B(a); | |
} | |
int main(int argc, char **argv) | |
{ | |
int k = argc == 2? strtol(argv[1], 0, 0) : 10; | |
printf("%d\n", A(FUN(MAKE_ARG(f1), MAKE_ARG(f_1), MAKE_ARG(f_1), | |
MAKE_ARG(f1), MAKE_ARG(f0)))); | |
return 0; | |
} |
/* setjmp的妙用 */ | |
jmp_buf env; | |
setjmp(env); // 获取机器寄存器的值 | |
void *stack_start; | |
int foo = 42; | |
stack_start = &foo; | |
/* do some */ | |
/* ... */ | |
void *stack_end; | |
int foo2 = 0; | |
stack_end = &foo2; /* 这样可以获取栈的使用大小 */ |
int cmp(void const *a, void const *b) | |
{ | |
return rand()-(RAND_MAX/2); | |
} | |
qsort(nums, nele, elesize, cmp); | |
/* 虽然效率受到影响 */ |
/* 在基于数组的栈时有如下技巧 */ | |
typedef struct { | |
size_t top; | |
size_t elesize; | |
void *mem; | |
}stack_t; | |
stack_t stk; | |
stk.top = 0; /* 初始为0表示没有元素 */ | |
/* 核心的一句,二进制数在增长时只有达到1111型时下一步才会达到10000型的界 */ | |
if ((stk.top+1) ^ (stk.top) > stk.top)) { | |
stk.mem = realloc(stk.mem, ((stk.top<<1)|0x1) * sizeof(stk.elesize)); | |
} | |
stk.meem[stk.top++] = ele; | |
/* 每次push元素时使用上面一句来检测 */ | |
/* NOTE 也就是 (num+1)^num > num 时num由1111型变为10000的关键! */ |
#if 0 /* C语言里不能实现。。。在javascript里可以! */ | |
switch (1) { | |
case (strcmp(name, "name1") && age == 21): | |
do_name1_21(); | |
break; | |
case (strcmp(name, "name2") && age == 21): | |
do_name2_21(); | |
braek; | |
/* .... */ | |
default: | |
break; | |
} | |
#endif | |
/* 实现 */ | |
if (strcmp(name, "name1") && age == 21)) | |
do_name1_21(); | |
else if (strcmp(name, "name2") && age == 21) | |
do_name1_21(); | |
else | |
do_other(); |
static int main_ret = 0; | |
static int test_count = 0; | |
static int test_pass = 0; | |
/* NOTE 也许可以加入 #name 来 stringze 名字,以便显示表达式 */ | |
/* 相等测试 */ | |
#define EXPECT_EQ_BASE(equality, expect, actual, format) \ | |
do { \ | |
++test_count; \ | |
if (equality) ++test_pass; \ | |
else { \ | |
fprintf(stderr, "%s: %d: expect: "format"\tactual: "format"\n", \ | |
__FILE__, __LINE__, expect, actual); \ | |
main_ret = 1; \ | |
} \ | |
} while (0) | |
/* 值近似测试 */ | |
#define EXPECT_SIM_BASE(expect, deviation, actual, format) \ | |
do { \ | |
++test_count; \ | |
if ((expect)-(deviation) <= (actual) && (actual) <= (expect)+(deviation)) { \ | |
++test_pass; \ | |
} else { \ | |
fprintf(stderr, "%s: %d: expect: ["format ", "format"]\tactual: "format"\n",\ | |
__FILE__, __LINE__, (expect)-(deviation), (expect)+(deviation), actual); \ | |
main_ret = 1; \ | |
} \ | |
} while (0) | |
#define TEST_EQ_INT(a, b) EXPECT_EQ_BASE((a)==(b), (a), (b), "%d") | |
#define TEST_NEQ_INT(e, a) EXPECT_EQ_BASE((e)!=(a), "NOT EQ", "EQ", "%s") | |
#define TEST_AS(asval, act) EXPECT_SIM_BASE(asval, 1, act, "%d") | |
#define TEST_TRUE(e) EXPECT_EQ_BASE((e), 1, (e), "%d") | |
#define TEST_FALSE(e) EXPECT_EQ_BASE(!(e), 0, (e), "%d") | |
#define TEST_NOTNULL(p) EXPECT_EQ_BASE(p, "NOTNULL", "NULL", "%s") | |
#define TEST_ISNULL(p) EXPECT_EQ_BASE(!p, "NULL", "NOTNULL", "%s") |
#include <stdio.h> | |
typedef void (declare_f)(int a); | |
/*上述是不同于 typedef void (*function_t)(int a); */ | |
#define DECLARE_F(name) void name(int a) | |
/* 声明 */ | |
declare_f f1; | |
DECLARE_F(f2); | |
declare_f *f3; /* a variable of pointing to a function. */ | |
void f1(int a) | |
{ | |
printf("%d\n", a); | |
} | |
void f2(int b) | |
{ | |
printf("f2: %d\n", b); | |
} | |
int main() | |
{ | |
f1(10); | |
f2(20); | |
f3 = f2; | |
f3(30); | |
return 0; | |
} |