嵌入式笔试专栏(第五天)

C/C++ 综合笔试题 Part 1

1. 请写出下列代码中各变量的大小及存储位置

#define SIZE 1024
typedef struct _Node {
    struct _Node *prev;
    struct _Node *next;
    unsigned char buf[SIZE]; 
    char a;
    int ib;
    short header;
    double *p;
    unsigned char (*buf_ptr)[SIZE];
    int (*fun[3])(char (*argA)(int, int), int);
} Node;

static double m = 2.1;
int data = 0;

int main(void) {
    int *p = NULL;
    p = malloc(sizeof(int));
    char *buf = "helloworld";
    static double m = 10.0;
    Node *node = (Node*)malloc(sizeof(Node));
    char buf_stack[10];
    int i = 0;
    extern int data;
    free(p);
    free(node);
}

存储分析:

m

(静态变量)

.data段

8字节

data

.data段

4字节

p

4字节

buf

(字符串常量)

只读段

指针 4字节,内容10字节

node

栈 + 堆

指针 4字节,结构体约1056字节

buf_stack

10字节

i

4字节

2. int i=(j=4,k=8,l=16,m=32); printf("%d", i); 输出是多少?

答案:

int i = (j = 4, k = 8, l = 16, m = 32); // 逗号表达式

逗号表达式返回最后一个表达式的值,即 m=32,因此 i=32,输出为:

32

3. 用递归方式写一个整数倒序输出函数

void print_reverse(int n) {
    if (n == 0)
        return;
    printf("%d", n % 10);
    print_reverse(n / 10);
}

示例调用:

print_reverse(1234); // 输出:4321

4. 求两个字符串的最长公共子串

char* longest_common_substring(const char* s1, const char* s2) {
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int maxlen = 0, end = 0;
    int dp[len1+1][len2+1];
    memset(dp, 0, sizeof(dp));

    for (int i = 1; i <= len1; i++) {
        for (int j = 1; j <= len2; j++) {
            if (s1[i-1] == s2[j-1]) {
                dp[i][j] = dp[i-1][j-1]+1;
                if (dp[i][j] > maxlen) {
                    maxlen = dp[i][j];
                    end = i;
                }
            }
        }
    }

    char *res = (char*)malloc(maxlen + 1);
    strncpy(res, s1 + end - maxlen, maxlen);
    res[maxlen] = '\0';
    return res;
}

5. 下列试题的结果是什么?为什么?

#define SQR(X) (X*X)
int a = 10;
int k = 2;
int m = 1;
a /= SQR(k+m) / SQR(k+m);

分析:

SQR(k+m) 展开为 (k+m*k+m) = 2 + 1*2 + 1 = 5,并非数学意义的平方,表达式变成:

a /= 5 / 5; // 即 a = a / 1

所以 a 结果仍是 10

6. i 最后等于多少?

int i = 1;
int j = i++;
if ((i > j++) && (i++ == j))
    i += j;

过程分析:

  • 初始:i = 1, j = i++ ⇒ j = 1, i = 2
  • 判断条件:(2 > 1) ⇒ true, 再判断 (2 == 2) ⇒ true
  • 所以 i += j ⇒ i = 2 + 2 = 4

最终:i = 4

7. 实现 atoi 函数

int atoi(const char *s) {
    int res = 0, sign = 1;

    while (*s == ' ') s++;
    if (*s == '-' || *s == '+') {
        if (*s == '-') sign = -1;
        s++;
    }

    while (*s >= '0' && *s <= '9') {
        res = res * 10 + (*s - '0');
        s++;
    }
    return res * sign;
}

8. 链表反转

struct Node {
    int val;
    struct Node *next;
};

struct Node* reverse(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* curr = head;

    while (curr) {
        struct Node* next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

9. 不使用库函数实现 strcat, strcmp, strcpy, strlen

int strlen(const char *s) {
    int len = 0;
    while (*s++) len++;
    return len;
}

char* strcpy(char* dst, const char* src) {
    char* ret = dst;
    while ((*dst++ = *src++));
    return ret;
}

int strcmp(const char* s1, const char* s2) {
    while (*s1 && (*s1 == *s2)) {
        s1++;
        s2++;
    }
    return *(unsigned char*)s1 - *(unsigned char*)s2;
}

char* strcat(char* dst, const char* src) {
    char* ret = dst;
    while (*dst) dst++;
    while ((*dst++ = *src++));
    return ret;
}

10. 编写 Makefile

项目结构:

.
├── main.c
├── Makefile
├── project_1
│   ├── example_1.c
│   └── example_2.c
├── project_2
    ├── example_3.c
    └── example_4.c

CC = gcc
CFLAGS = -I. -Wall

SRCS = main.c \
       project_1/example_1.c \
       project_1/example_2.c \
       project_2/example_3.c \
       project_2/example_4.c

OBJS = $(SRCS:.c=.o)

TARGET = main

$(TARGET): $(OBJS)
	$(CC) -o $@ $^

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)

嵌入式笔试专栏 文章被收录于专栏

本专栏系统整理了嵌入式方向笔试中常见的知识点和高频考题,涵盖基础理论、常用算法、C语言陷阱、操作系统原理、驱动开发、常见外设通信协议(如 I2C/SPI/UART)、RTOS、Linux 内核、以及实用电路知识等内容。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务