[C] Summary of wrong questions in winter vacation

Posted by nitroxman on Tue, 15 Feb 2022 05:49:42 +0100

choice question

eg1

What is the output of the following code ()

char a=101;
int sum=200;
a+=27;sum+=a;
printf("%d\n",sum);

A: 327    B: 99    C: 328    D: 72

Answer analysis:
Correct answer: D
char is a signed type, accounting for 1 byte, that is, 8 bits, of which the highest bit is the sign bit, and the value range is - 128 ~ 127; a=101+27=128128 means 10 million, which is put in memory as a complement. The symbol bit is 1. When adding and calculating with sum of type int, the integer will be raised, the high bit will be supplemented by 1, and then the original code will be - 128, sum=200+(-128)=72

eg2

Assuming that the function prototype and variables are described below, the legal call is ()

void f(int **p);
int a[4]={1,2,3,4};
int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *q[3]={b[0],b[1],b[2]};

A: f(a);    B: f(b);    C: f(q);    D: f(&a);

Answer analysis:
Correct answer: C
Option a, when f(a) passes a parameter, a will degenerate into an address pointing to its first element. The type is int *, which is inconsistent. Option B, B is a two-dimensional array. When passing parameters, it will degenerate into a pointer to its first element, that is, the address of b[0]. The type of b[0] is int [4], so the type of & b[0] is int()[4], which is inconsistent. D option, & A is the address of array a, and its type is int()[4], which is inconsistent. C option, q is a pointer array. During initialization, b[0], b[1] and b[2] are used. At this time, b[0], b[1] and b[2] will degenerate into pointers to each first element (int * type, so the type is consistent, so they can be initialized). When Q passes a parameter, it degenerates into a pointer to its first element, that is, int * *, which conforms to 33

eg3

Suppose that the C language program uses malloc to apply for memory, but does not lose free, then when the process is kill ed, the operating system will ()
A: Memory leak B: segmentation fault C: core dump D: none of the above

Answer analysis:
Correct answer: D
No matter how much memory is used by the user, the process of malloc will be reclaimed at the end of the program

eg4

What is the output result of the following program ()

#include <stdio.h>
typedef struct List_t
{
struct List_t* next;
struct List_t* prev;
char data[0];
}list_t;
int main()
{
printf("%d",sizeof(list_t));
return 0;
}

A: 4byte    B: 8byte    C: 5byte    D: 9byte

Answer analysis:
Correct answer: B
char data[0] in the title or written as char data [] is a flexible array member; When the computer structure is large, data does not occupy the space of struct, but exists as a symbolic address. Therefore, the value of sizeof is the byte occupied by two pointers, that is, 4 + 4 = 8 bytes

eg5

In the following statements about C language, the wrong one is ()
A: Memory leakage generally refers to that a program applies for a piece of memory and does not release the memory in time after it is used, resulting in a large amount of memory occupied by the program, but not used or released
discharge
B: You can apply for memory blocks that exceed the physical memory size of the machine through malloc(size_t) function call
C: You cannot directly return a used memory to the operating system through the memory release function free(void *). The free function only dynamically requests the use of memory
Power release
D: You can directly apply for physical memory through the memory allocation function malloc(size_t)

Answer analysis:
Correct answer: D
The memory released by free may not be directly returned to the operating system, but may not be released until the end of the process. malloc cannot directly apply for physical memory. It applies for virtual memory

eg6

The output of the following code is ()

#include <stdio.h>
#define a 10
void foo();
int main()
{
    printf("%d..", a);
    foo();
    printf("%d", a);
    return 0;
} 
void foo()
{
#undef a
#define a 50
}
A: 10..10   B: 10..50    C: Error    D: 0

Answer analysis:
Correct answer: A
In the preprocessing stage, define replaces all a in main with 10. In addition, whether inside or outside a function, define starts from the definition to the end of the file, so if you put the definition of foo function on main, the result will be 50... 50

Programming problem

eg1


Brute force solution: compares each character in the string with all characters., Whether the breaks are equal.

int FirstNotRepeatingChar(char* str ) {
    // write code here
    for(int i = 0; i < strlen(str); i++)
    {
        int flag = 0;//Judge whether the i th character can be found later
        for(int j = 0; j < strlen(str)-i; j++)
        {
            if(j != i && str[i] == str[j])
            {
                flag = 1;
                break;
            }
        }
        if(flag == 0)
        {
            return i;
        }
    }
    return -1;
    
}

eg2


Problem solving ideas
Count the number of occurrences of each character in S. if s can form a palindrome string, only an odd number of occurrences of one character can be allowed at most.

bool canPermutePalindrome(char* s){
    char a[256] = {0};
    for(int i = 0; i < strlen(s); i++)
    {
        a[s[i]]++;
    }
    int count = 0;
    for(int i = 0; i < 128; i++)
    {
        if(a[i] % 2 != 0)
        {
            count++;
        }
        if(count > 1)
        {
            return false;
        }
    }
    return true;
}

eg3

char* replaceSpaces(char* S, int length0)
{
    int count = 0;//Count the number of occurrences of spaces
    int afterLength = 0;//Count the length after replacing spaces with% 20

    for(int i = 0; i < length0; i++)
    {
        if(S[i] == ' ')
        {
            count++;
        }
    }
    afterLength = length0 + 2 * count;
    S[afterLength] = '\0';//Set the end of string flag first
    int j = 1;//Record the location of afterLenth
    for(int i = length0 - 1; i >=0; i--)
    {
        if(S[i] != ' ')
        {
            S[afterLength - j] = S[i];
            j++;
        }
        else
        {
            S[afterLength - j] = '0';
            S[afterLength - j - 1] = '2';
            S[afterLength - j - 2] = '%';
            j += 3;
        }
    }
    return S;
}

eg4


[answer analysis]:
Note: this problem is the exchange of odd and even bits of binary. You only need to move the even bit to the left and the odd bit to the right

int exchangeBits(int num)
{
    int odd = 0b10101010101010101010101010101010;//Reserved even digits
    int even = 0b01010101010101010101010101010101;//Reserved odd digits
    odd &= num;
    even &= num;
    return (odd >> 1) + (even << 1);
}

eg5

1. [answer analysis]:
How many mantissa zeros are there in the factorial of a number? We need to be flexible here. How does the mantissa zero come from? It is multiplied by 10, and 10 = 2 * 5. There are many factors of 2 in factorial, but there are not many 5. Therefore, we only need to count how many times 5 appears.

  • Violence method: traverse the multiples of 5 and judge how many 5's there are in each multiples of 5. For example, 25 = 5 * 5, so 25 needs to be counted twice. This method is direct, but the efficiency is not high, because when the number is large, the number of cycles is more
  • Better idea: take the factorial of 10 as an example= 12345678910, 5 will appear every five numbers, so 10 / 5 is the number of times 5 appears.
    But the special thing is 25125... Which contains multiple 5, 25 = 55125 = 555... They are only counted once. There is one multiplier left for 25 and one multiplier left for 5125. Therefore, it is necessary to divide by 5 again to get the number of the remaining 5 until the final result is less than 5
int trailingZeroes(int n)
{
    //Time complexity O(logN)
    int count = 0;
    while(n >= 5)
    {
        count += n / 5;
        n /= 5;
    }
    return count;

    //Time complexity O(N*logN)
    /*int count = 0;
    for(int i = 0; i <= n; i += 5)
    {
        int num = i;
        while(num > 0 && num % 5 == 0)
        {
            count++;
            num /= 5;
        }
    }
    return count;
}

eg6

In fact, this problem itself is not difficult. With a specific formula, you can get the result by directly circulating and deducing later. However, when there are multiple test cases, the efficiency will be much worse each time the k-th data is recalculated. After all, each number must be recalculated from scratch.
Therefore, after entering the program, you can first form a large sequence, and you can take out the first few in the subsequent test cases directly

#include <stdio.h>

int main()
{
    int arr[1000000] = {1, 2};
    for(int i = 2; i < 1000000; i++)
    {
        arr[i] = (2 * arr[i - 1] + arr[i - 2]) % 32767;
    }
    int n = 0;
    scanf("%d", &n);
    int k = 0;
    while(n)
    {
        scanf("%d", &k);
        printf("%d\n", arr[k - 1]);
        n--;
    }
    return 0;
}

Topics: C Back-end