Problem 1. Basic knowledge
Problem 2. Polynomial evaluation
Input format
Output format
Example
Notes
Problem 3. GCC argument descriptor
Problem background
Problem description
1. -Wall
2. -Wpedantic
3. -Wextra
4. -Werror
5. -o xxx
6. -I xxx
7. -std=xxx
8. Other
Notes
Example
Problem 4. 6174
Hint
Input format
Output format
Example
Note
Problem 5: CPU emulator
Description
Input format
Output format
Example
Note
Problem 1. Basic knowledge
1. Suppose c is a variable of type char. If c is a decimal digit character, how
can we obtain its numeric value?
int(c)
c - 48
c - '0'
c - '\0'
*(int *)&c
2. Regarding undefined behaviors, which of the following statements is/are
true?
An undefined behavior results in one of a set of valid results. For example,
the following code (assuming int is 32-bit) will assign the variable x with
some value, but the value is not valid.
int ival = 10000000;
int x = ival * ival;
An undefined behavior means that there are no restrictions on the behavior
of the program. The standard does not require such programs to do
anything meaningful.
An undefined behavior means that two or more behaviors are permitted by
the standard and that the compiler will choose a meaningful one. The
behavior remains unchanged when the program is run again, although we
don't know what the behavior is.
Correct C programs shall not have undefined behaviors.
3. Suppose int is 32-bit and long long is 64-bit. Select the code snippet(s)
that involve(s) integer overflow.
int x = 42 / 0;
int ival = 1000000;
long long llval = ival * ival;
unsigned uval = -42;
unsigned u1 = 10000000;
unsigned u2 = u1 * u1;
4. Select the code snippet(s) that involve(s) undefined behavior.
int random(void) {
int x;
return x;
}
int main(void) {
printf("%d\n", random());
}
unsigned uval = -5;
printf("%u\n", uval);
int table[100];
int exists_in_table(int value) {
for (int i = 0; i <= 100; ++i)
if (table[i] == value)
return 1;
return 0;
}
int foo(int value) {
printf("%d\n", value);
}
int main(void) {
int x = 42;
int y = foo(x);
printf("%d\n", x + y);
}
int i = 42;
printf("%d%d\n", i, i++);
double pi = 3.14;
printf("%d\n", pi);
5. Read the following code.
void swap(int *pa, int *pb) {
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
int main(void) {
int x = 10, y = 15;
swap(&x, &y);
printf("%d %d\n", x, y);
}
(1) Which of the following statements is/are true?
The asterisk (*) in the function parameter declaration int *pa is a part of
int *, meaning that pa is a pointer to int.
The asterisk (*) in the statement int tmp = *pa is the dereference operator,
which is used to access the object that pa points to.
The asterisk (*) in the statement *pb = tmp is the pointer symbol, meaning
that pb is a pointer.
The asterisk (*) in the statement *pb = tmp is the dereference operator,
which is used to access the object that pb points to.
(2) Which of the following statements is/are true?
If we rewrite the function swap as follows
void swap(int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
and replace swap(&x, &y) with swap(x, y) in the main function, the values
of x and y are still exchanged successfully.
The parameter declarations of swap can be rewritten as int *pa, pb,
because pa and pb are of the same type.
The parameter declarations of swap can be rewritten as int *pa, *pb,
because pa and pb are of the same type.
The function swap will output the values of *pa and *pb.
None of the above.
(3) Write down the type of each expression. For pointer types, place exactly one
space between the pointee type and the first asterisk, and no spaces between
consecutive asterisks (e.g. int *, int **, or int ***, but not int* or int * *).
Expression pa *pa &pa x &x
Type
6. Read the following code.
int min_element(int *array, int l, int r) {
int pos = l;
while (l < r) {
if (array[l] < array[pos])
pos = l;
++l;
}
return pos;
}
int a[] = {1, 4, 2, 8, 5, 7};