Skip to content

Instantly share code, notes, and snippets.

@leetking
Last active August 4, 2017 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leetking/730ef875d16b9f3db1187d43640de8be to your computer and use it in GitHub Desktop.
Save leetking/730ef875d16b9f3db1187d43640de8be to your computer and use it in GitHub Desktop.
C小技巧
/*
* 注释嵌套测试
*/
#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;
}

limits.h和float.h

limits.h

  • INT_MAX

float.h

  • DBL_MAX
/*
* 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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment