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; | |
| } |