据悉,深圳某工程师沦为C语言笔试枪手

嵌入式Linux

共 2360字,需浏览 5分钟

 ·

2020-12-31 16:42


事情是这样的,昨晚晚上,有个网友发消息给我,说他有几道C语言笔试题不会写,所以,就出现了解题的这一幕。

文章中,我只讲解了一部分,有一些题目觉得没必要讲,然后我在pdf上做了注释,想看的在公众号留言「20201227」获取pdf文档。

1、第一题

#include "stdio.h"

int x = 2;
int y = 0

int main()
{
    if(x){
      y++;
    }
    printf("%d\n",y);
    getchar();
    return 0;
}

这是送分题,就没有怎么好说的了,答案 1 .

2、解析一道比较有坑的。

#include "stdio.h"
#include "string.h"

int a()
{
    static int i =0;
    if(i>=1)
    {
        return --i;
    }
    return i++;
}

int main()
{
    int A1 = 0;
    int A2 = 0;
    int A3 = 0;

    A1 = a();
    A2 = a();
    A3 = a();

    printf("%d,%d,%d\n",A1,A2,A3);
    getchar();
    return 0;
}

这个题目,主要要搞清楚,return i++ ,是先return i++,那就问题不大了。

3、这题应该好好说一下

#include "stdio.h"

int arg[] = {0,1,2,3};
int *p = &arg[1];
int v = 0;
int w = 0;

int main()
{
    int i;
    *(p++)+= 5;
    v = *p; 
    *p = *p +5;
    w=*p;
    printf("v:%d\n",v);
    printf("w:%d\n",w);

    for(i=0;i<4;i++)
      printf("arg[%d]=%d\n",i,arg[i]);

    getchar();
    return 0;
}

这题乍一看其实没有什么难度,但是实际写的时候,容易出问题,特意拿出来说一下。

核心在这行代码 *(p++)+= 5;

分解出来就是 取得p指向的值,然后 +=5 ,再让p指向下一个位置。

反汇编代码是这样的

mov rax,QWORD PTR [rip+0x2f0f] # 404040 


lea rdx,[rax+0x4] //这是让指针指向下一个位置保存的寄存器
mov QWORD PTR [rip+0x2f04],rdx # 404040 


mov edx,DWORD PTR [rax] //这是用来也 5 运算的寄存器
add edx,0x5
mov DWORD PTR [rax],edx

如果知道了这点,其他的就容易很多了。

    int i;
    *(p++)+= 5;  //arg[1] = 6 p指向arg[2]
    v = *p; //v = arg[2] = 2
    *p = *p +5; //arg[2] = 2+5 = 7
    w=*p; //w = 7
    printf("v:%d\n",v);
    printf("w:%d\n",w);

大家可以自己试试,如果把 *(p++)+= 5 改成 *(++p)+= 5 结果如何呢?

4、链表编程题

下面的题目我只写了第一题,后面的一题没有继续下,写链表的题目,我建议画一张链表的连接图,这样写代码的时候就会特别清晰了。

大家有不懂的,可以尽管问,另一个题目,欢迎留言写出来,我觉得这样的题目简单,但是也比较考验思维能力。

题目:

链表图形

直接上代码吧

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

typedef struct _STUDENT_INFO
{
 int IDx;
 char Name[32];
 struct  _STUDENT_INFO *Next;
} STUDENT_INFO_DEF;



STUDENT_INFO_DEF * creat(void)
{
    STUDENT_INFO_DEF * h = (STUDENT_INFO_DEF *)malloc(sizeof(STUDENT_INFO_DEF));
    h->Next = NULL;
    return h;
}


int InsertStu(STUDENT_INFO_DEF *head,STUDENT_INFO_DEF stu)
{
    if(head == NULL){
        printf("head NULL\n");
        return -1;
    }

    STUDENT_INFO_DEF * temp = head;
 STUDENT_INFO_DEF * new = (STUDENT_INFO_DEF *)malloc(sizeof(STUDENT_INFO_DEF));
    
    new->IDx = stu.IDx;
    strncpy(new->Name,stu.Name,strlen(stu.Name));
    new->Next = NULL;

    while (temp->Next != NULL) {temp=temp->Next;}
    
    temp->Next = new;
    printf("[InsertStu] IDx:%d Name:%s Ok\n",new->IDx,new->Name);
    return (0);
}

/*遍历链表*/
int TraverseStu(STUDENT_INFO_DEF *head)
{
    STUDENT_INFO_DEF * temp = head;
    if(head == NULL){
        printf("head NULL\n");
        return -1;
    }

    while(temp->Next!=NULL)
    {
        temp = temp->Next;
        printf("[TraverseStu]IDx:%d Name:%s\n",temp->IDx,temp->Name);
    }

    return (0);
}

int FindAndDelete(STUDENT_INFO_DEF *head,STUDENT_INFO_DEF stu)
{
    STUDENT_INFO_DEF * temp = head;
    STUDENT_INFO_DEF * temp1 = NULL;

    if(head == NULL){
        printf("head NULL\n");
        return -1;
    }

    while(temp->Next!=NULL)
    {
        temp = temp->Next;
        if(temp->IDx == stu.IDx) break;
    }

    temp1 = temp->Next;
    temp->Next = NULL;
    while(temp1!=NULL)
    {
        free(temp1);
        temp1 = temp1->Next;
    }

    printf("[FindAndDelete]\n");
    return 0;
}


int main()
{
    int i;
    /*创建链表头*/
    STUDENT_INFO_DEF *head; 
    STUDENT_INFO_DEF stu;

    head=creat();
 
    for(i=0;i<5;i++)
    {
        stu.IDx = i+1;
        snprintf(stu.Name, strlen("student")+2, "student%d", i+1);
        InsertStu(head,stu);
    }

    TraverseStu(head);

    stu.IDx = 2;
    FindAndDelete(head,stu);

    TraverseStu(head);

    getchar();
 return 0;
}


代码输出

weiqifa@bsp-ubuntu1804:~/c/mianshi$ gcc lianbiao.c && ./a.out
[InsertStu] IDx:1 Name:student1 Ok
[InsertStu] IDx:2 Name:student2 Ok
[InsertStu] IDx:3 Name:student3 Ok
[InsertStu] IDx:4 Name:student4 Ok
[InsertStu] IDx:5 Name:student5 Ok
[TraverseStu]IDx:1 Name:student1
[TraverseStu]IDx:2 Name:student2
[TraverseStu]IDx:3 Name:student3
[TraverseStu]IDx:4 Name:student4
[TraverseStu]IDx:5 Name:student5
[FindAndDelete]
[TraverseStu]IDx:1 Name:student1
[TraverseStu]IDx:2 Name:student2


推荐阅读:
专辑|Linux文章汇总
专辑|程序人生
专辑|C语言
我的知识小密圈

浏览 40
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报