A set of test questions that help you understand C Language

Source: Internet
Author: User
I found a very interesting set of C language test questions on this website (http://stevenkobes.com/ctest.html). If you are hiring a C language developer or are learning C language, it is worth doing.

If you haven't done so, don't read the following content for the time being, it is best to complete it yourself.

OK, assuming your answer is not completely correct, then you can continue to watch, otherwise, the following content is a piece of cake for you, not worth watching.

first question:

#include <setjmp.h>
static jmp_buf buf;
int main (void)
{
volatile int b = 3;
if (setjmp (buf)! = 0)
{
printf ("% dn", b);
exit (0);
}
b = 5;
longjmp (buf, 1);
}
The output is A) 3 B) 5 C) 0 D) None

The answer is B, which is output 5.

The key point is to understand setjmp and longjmp. (Http://en.wikipedia.org/wiki/Setjmp.h) The first time you run to setjmp, it will set jmp_buf and then return 0. When longjmp is called, the non-zero value in longjmp will be returned as the return value of setjmp (If the value parameter of longjmp is 0, setjmp will return 1 after recovery, that is, setjmp will never return when it is restored to the setjmp storage point 0).

The setjmp-longjmp combination is similar to the save and read function in games, and is often used for C ++-like exception recovery operations.

Second question:

struct node
{
int a;
    int b;
    int c;
};
struct node s = {3, 5, 6};
struct node * pt = & s;
printf ("% dn", * (int *) pt);
The return result is 3, which is relatively simple. Pt is a pointer to the structure s, then pt is converted to an int pointer, dereferenced, and an int value is taken out.

Let's change the title to the following code:

struct node
{
char a;
    char b;
    short c;
    int d;
};
struct node s = {3, 5, 6, 99};
struct node * pt = & s;
printf ("% Xn", * (int *) pt);
It should be noted that generally 32-bit C compilers think that char is 8bit, short is 16bit, and int is 32bit, so node should be exactly aligned in memory, that is, there is no gap between the members of abc. The final result should be 60503. If not, you are welcome to tell me your specific compilation environment and hardware configuration.

Third question:

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;
}
The easiest way to solve this problem is to do a deductive calculation on paper and run step by step to get the answer. There is no complicated C language concept in it.

The fourth question:

int a [5] = {1, 2, 3, 4, 5};
int * ptr = (int *) (& a + 1);
printf ("% d% dn", * (a + 1), * (ptr – 1));
This question is actually a pointer to an array. & A is an implicit pointer to an int [5] array, which is different from int * ptr. If you really want to define this pointer, it should be int (* ptoa ) [5]. So each time ptoa adds one, it is equivalent to stride over the memory step size of int a [5] (that is, 5 int lengths), that is, & a + 1 actually points to a [5]. This position is illegal, but the forced conversion of ptr caused the subsequent memory step size of ptr-1 to be changed to an int length, so ptr-1 actually pointed to a [4]. As for * (a + 1), there is nothing to say, the value is 2.

Question five:

void foo (int [] [3]);
int main (void)
{
int a [3] [3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
foo (a);
printf ("% dn", a [2] [1]);
return 0;
}
void foo (int b [] [3])
{
++ b;
b [1] [1] = 9;
}
In fact, it is the same as the previous question. The step length of ++ b is actually 3 ints, that is, after the ++ b operation, b points to the beginning of the array {4,5,6}, and b [1] That is {7,8,9}, b [1] [1] is actually the value of 8, which is a [2] [1] in the main function.

Question 6:

int a, b, c, d;
a = 3;
b = 5;
c = a, b;
d = (a, b);
printf ("c =% d", c);
printf ("d =% dn", d);
This actually has two C language knowledge points, one is that the equal sign operator has higher precedence than the comma operator, and the other is that the comma operator is equivalent to the expression of the first half of the comma and then the second half of the expression Value. So c is equal to a (the equal sign is calculated first), and d is equal to b (the comma expression returns b).

Question 7:

int a [] [3] = {1, 2, 3, 4, 5, 6};
int (* ptr) [3] = a;
printf ("% d% d", (* ptr) [1], (* ptr) [2]);
++ ptr;
printf ("% d% dn", (* ptr) [1], (* ptr) [2]);
It is still a 2-dimensional array-related problem, ptr is a pointer to the int [3] array, and first points to a [0], so (* ptr) [1], (* ptr) [2] is a [0] [1] , a [0] [2]. Then ++ ptr, which is equivalent to ptr pointing to a [1], then you get a [1] [1], a [1] [2], so the result is 2, 3, 5, 6.

Question 8:

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;
}
The test here is to return a pointer. Generally speaking, a function that returns a pointer must have a memory application operation such as malloc. When the pointer type is passed in, the content pointed to by the pointer is modified. If you want to modify the pointer itself, you need to pass in a pointer to the pointer.

Ninth question:

int i = 3; int j;
j = sizeof (++ i + ++ i);
printf ("i =% d j =% dn", i, j);
The content of this question test is actually sizeof. If an expression is calculated, the expression will not be calculated, that is, regardless of addition, subtraction, and subtraction, sizeof calculates the size for i. On a 32-bit machine, this j should be 4.

I extended the code a bit to see if everyone can think of the results:

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);
Question 10:

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% dn", a, b);
return 0;
}
void f1 (int * p, int q)
{
int tmp = * p; * p = q; q = tmp;
}
The array p of function pointers is barely a knowledge point. Another knowledge point is mentioned in the eighth question. For parameters such as int q, its content will not be modified. And * p can modify what p points to.

Question 11:

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);
}
}
This problem is fully understood by debugging. The main point of knowledge is the recursive call, and the return value of the pre-post decrement operation.

Question 12:

typedef int (* test) (float *, float *);
test tmp;
It is also a type of problem that often appears. It analyzes complex pointer definitions. In fact, K & R (5.12) also introduces how to interpret it. Unfamiliar friends can try to practice the bsearch, qsort and signal functions in the standard library.

Question 13:

char p;
char buf [10] = {1, 2, 3, 4, 5, 6, 9, 8};
p = (buf + 1) [5];
printf ("% dn", p);
That is, p actually points to * (buf + 1 + 5), and it is even more weird to write p = 5 [buf +1]; the same result.

Question 14:

Similar to the thirteen questions, the array is made a little weird, (p + = sizeof (int)) [-1]; It is equivalent to * (p + sizeof (int) + (-1)).

Question 15:

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 ("% dn", ripple (3, 5, 7));
return 0;
}
This question is also two points of knowledge. One is the definition of the variable parameter function and how to implement it. Va_arg will take 5, 7 in turn. Another knowledge point is i & = i-1, which actually calculates the number of 1s in the binary form of i. Each calculation will reduce the 1 in the least significant bit. For example 7 binary representation is 111. The calculation result of i & = i –1 is 110, 100,000 (that is, 0). A lot of similar tricks are covered in the book Hacker's Delights.

Question sixteen:

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 ("% dn", j);
return 0;
}
As long as you understand the true meaning of static local variables, this question is a piece of cake.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.