# C语言趣味题目

http://stevenkobes.com/ctest.html

—————————————–

——————————————–

OK，假设你做的答案没有完全正确，那你可以继续看下去了，否则，后面内容对你来说就是小菜一碟，不值得看。

——————————————–

#include <setjmp.h>
static jmp_buf buf;
int main(void)
{
volatile int b = 3;
if (setjmp(buf) != 0)
{
printf(“%d\n”, b);
exit(0);
}
b = 5;
longjmp(buf, 1);
}

setjmp-longjmp组合的用处类似于游戏中的存盘读盘功能，经常被用于类似C++的异常恢复操作。

struct node
{
int a;      int b;      int c;
};
struct node s = { 3, 5, 6 };
struct node *pt = &s;
printf(“%d\n”, *(int*)pt);

struct node
{
char a;   char b;  short c;   int d;
};
struct node s = { 3, 5, 6, 99 };
struct node *pt = &s;

printf(“%X\n”, *(int*)pt);

int foo(int x, int n){
int val = 1;
if (n > 0)
{
if (n % 2 == 1) val *= x;
val *= foo(x * x, n / 2);
}
return val;
}

int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int*)(&a + 1);
printf(“%d %d\n”, *(a + 1), *(ptr – 1));

void foo(int[][3]);
int main(void)
{
int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
foo(a);
printf(“%d\n”, a[2][1]);
return 0;
}

void foo(int b[][3])
{
++b;
b[1][1] = 9;
}

int a, b, c, d;
a = 3;
b = 5;
c = a, b;
d = (a, b);

printf(“c=%d  “, c);
printf(“d=%d\n”, d);

int a[][3] = {1, 2, 3, 4, 5, 6};
int (*ptr)[3] = a;

printf(“%d %d “, (*ptr)[1], (*ptr)[2]);

++ptr;
printf(“%d %d\n”, (*ptr)[1], (*ptr)[2]);

int *f1(void)
{
int x = 10;   return &x;
}
int *f2(void)
{
int *ptr;   *ptr = 10;   return ptr;
}
int *f3(void)
{
int *ptr;   ptr = malloc(sizeof *ptr);   return ptr;
}

int i = 3;   int j;
j = sizeof(++i + ++i);
printf(“i=%d j=%d\n”, i, j);

short m;    int n;     double dn;
int j = sizeof ( m + n);
int k = sizeof ( n + n);
int l = sizeof ( m);
int l2 = sizeof (m * m);
int l3 = sizeof (m + dn);
int l4 = sizeof (m + m);

void f1(int*, int);
void (*p[2])(int*, int);
int main(void)
{
int a = 3;
int b = 5;
p[0] = f1;
p[1] = f1;
p[0](&a, b);
printf(“%d %d “, a, b);
p[1](&a, b);
printf(“%d %d\n”, a, b);
return 0;
}

void f1(int *p, int q)
{
int tmp = *p;   *p = q;   q = tmp;
}

void e(int);
int main(void)
{
int a = 3;
e(a);

putchar(‘\n’);
return 0;
}

void e(int n)
{
if (n > 0)
{
e(–n);
printf(“%d “, n);
e(–n);
}
}

typedef int (*test)(float*, float*);
test tmp;

char p;
char buf[10] = {1, 2, 3, 4, 5, 6, 9, 8};
p = (buf + 1)[5];
printf(“%d\n”, p);

int ripple(int n, …)
{
int i, j, k;
va_list p;
k = 0;
j = 1;
va_start(p, n);
for (; j < n; ++j)
{
i = va_arg(p, int);
for (; i; i &= i – 1)
++k;
}
return k;
}

int main(void)
{
printf(“%d\n”, ripple(3, 5, 7));
return 0;
}

int counter(int i)
{
static int count = 0;
count = count + i;
return count;
}

int main(void)
{
int i, j;
for (i = 0; i <= 5; i++)  j = counter(i);
printf(“%d\n”, j);
return 0;
}

## “C语言趣味题目”的7个回复

1. 萬能的va_arg，想當年用它寫不個…函數是多麼的驕傲啊。

2. resty说道：

第二题在我处就不同
编译条件gcc 3.4.5
如果是
struct node
{
char a; char b; short c; int d;
};
编译结果sizeof(node) = 8
而sizeof(char) = 1确是

3. Lunar说道：

sizeof(m+n) 取的字节长的类型，问一下有什么依据么？

4. admin说道：

Re Lunar
取得是表达式计算结果，比如double * othertype，结果都应该为double，其它类似这个规则，具体文档我记不太清哪里能找到。

5. hfw_1987说道：

第四题
也就是说&a + 1其实就是指向了a[6]这个位置
==========================
这个错了吧，应该是a[5]这个位置吧，数组是从a[0]开始的啊

6. admin说道：

Re hfw_1987 : 这的确是有错误，已经修正了。