C语言笔试面试必刷题

🎊【面经】专题正在持续更新中,内含C语言,数据结构,Linux,网络编程等✨,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏

🪔本系列专栏 -  ​​​​​​面经

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 - 勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇须知少日拏云志,曾许人间第一流。

目录

关键字

数组与指针

各类定义

结构体、共用体、枚举

排序算法


关键字

        谈谈static的作用?

        在C语言中,static关键字有多种作用。首先,它可以用于隐藏全局变量或函数,这在同时编译多个文件时非常有用。其次,static还可以用于修饰局部变量和全局变量,这些变量在整个程序运行期间都存在,且只有一份拷贝,而且这些变量只在当前文件下可见,其他文件无法引用这些变量。static修饰的未初始化的全局或局部变量存储在.data,static修饰的已初始化的全局或局部变量存储在.bss段。

        谈谈const的作用?

        在C语言中,const关键字的主要作用是限定一个变量不允许被改变,产生静态作用。

        编译器一般不为const变量分配内存,而是将它保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作。

        谈谈volatile的作用?

        volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

        const和volatile是否可以同时修饰一个变量?有什么特殊含义?

        可以放一起修饰一个变量。

        同时修饰一个变量的含义表示一个变量在程序编译期不能被修改且不能被优化;在程序运行期,变量值可修改,但每次用到该变量的值都要从内存中读取,以防止意外错误。

        sizeof与strlen的区别?

        他们都是用于计算内存大小的。sizeof是C语言中的一个运算符,而strlen是一个函数;sizeof考研用于任意类型的数据,而strlen只能用于以空字符结尾的"/0"的字符串;sizeof计算的是类型或变量所占用的内存字节数('\0'计入),而strlen计算的是字符串中的字符个数(遇到'\0'截止,且'\0'不计入);sizeof在编译时就能确定结果,而strlen在运行时才能确定结果。

数组与指针

        数组与指针的区别 ?

        定义与初始化:数组是一种数据结构,用来存储多个相同类型的数据,他的大小在定义的时候就已经确定了,而且不能改变。指针是一种变量,存储的是一个地址,这个地址指向另一个变量或者内存空间,他的大小取决于相同的位数(32位系统位4字节,64位系统为8字节)。

        存储方式:数组一般存储在静态区或者栈上,他的地址是连续的,可以用下标访问;指针考研存储在任何地方,地址不连续,可以用解引用符*来访问。

        可变性:数组名是一个常量,指向数组的首地址,不能被赋值和修改;指针是一个变量,考研被赋值或修改,考研指向不同的地址空间。

        谈一谈数组指针与指针数组?

        数组指针和指针数组是两种不同的数据类型。数组指针本质是一个指针,它指向一个数组,也就是说它存储的是一个数组的地址。指针数组是一个数组,它的元素都是指针,也就是说它存储的是多个地址。

        数组指针的声明方式是类型 (*指针名) [长度]。指针数组的声明方式是类型 *数组名 [长度]。

        数组指针的大小取决于系统的位数,一般为4字节或8字节。指针数组的大小取决于数组的长度和元素类型,一般为长度乘以4字节或8字节。

       数组指针可以通过解引用符*来访问或修改它所指向的数组,例如(*p)[0] = 1表示将p所指向的数组的第一个元素赋值为1。指针数组可以通过下标来访问或修改它的元素,例如p[0] = &a表示将p的第一个元素赋值为变量a的地址。

        数组指针可以用于作为函数参数传递多维数组,例如void func(int (*p)[10])表示func函数接受一个包含10个int元素的一维数组或者一个包含10列的二维数组作为参数。指针数组可以用于存储不同长度或类型的数据,例如字符串或结构体等。

        一维数组与二维数组用指针怎么表示?

        如果有一个一维数组int a[5] = {1, 2, 3, 4, 5};,那么可以用一个指针int *p = a;来表示它。通过指针和下标可以访问或修改数组中的元素,例如p[0] = 10;表示将数组第一个元素赋值为10。

        如果有一个二维数组int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};,那么可以用一个指向数组的指针int (*p)[4] = a;来表示它。通过指针和下标可以访问或修改二维数组中的元素,例如p[0][0] = 10;表示将二维数组第一个一维数组的第一个元素赋值为10。

        指针占的字节数?

        指针是一种变量,它可以存储一个地址,指向另一个变量或内存空间。指针的大小取决于系统的位数和计算机的架构。

        在32位系统中,指针通常占用4个字节,因为内存地址可以用32位二进制数表示。

        在64位系统中,指针通常占用8个字节,因为内存地址可以用64位二进制数表示。

        谈一谈函数指针与指针函数?

        函数指针与指针函数是两种不同的数据类型。函数指针是一个指针,指向一个函数,他存储的是一个函数的地址;指针函数是一个函数,返回值是一个指针。

        函数指针的声明方式是类型说明符 (*函数名) (参数),例如int (*fun) (int x, int y)表示fun是一个指向有两个int类型参数和int类型返回值的函数的指针。指针函数的声明方式是类型 *函数名 (参数),例如int *fun (int x, int y)表示fun是一个有两个int类型参数和返回一个int类型指针的函数。

        函数指针的大小取决于系统的位数,一般为4字节或8字节。指针函数的大小取决于函数的定义,一般为函数体中语句所占用的字节数。

各类定义

定义一个整型数

int a;

定义一个指向整型数的指针

int *p;

定义一个指向指针的指针,他指向的指针指向一个整型数

int **p;

定义一个有10个整型数的数组

int arr[10];

定义一个有10个指针的数组,该指针指向一个整型数(指针数组)

int *arr[10];

定义一个指向有10个整型数数组的指针(数组指针)

int (*arr)[10];

定义一个指向函数的指针,该函数有一个整型数参数并返回以后整型数(函数指针)

int (*fun)(int );

定义一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(指针函数)

int (*fun[10])(int );

结构体、共用体、枚举

谈一谈你会结构体,共用体,枚举的看法?

        结构体是由多个不同类型的成员变量组成的数据类型,它可以用来表示具有多种属性的对象或记录。结构体的每个成员都占用独立的内存空间,结构体的总大小等于或大于各个成员的大小之和。结构体可以通过.运算符来访问或修改其成员变量的值。

        共用体是由多个不同类型的成员变量组成的数据类型,它可以用来表示多种可能性的数据。共用体的所有成员都共享同一块内存空间,共用体的总大小等于最大成员的大小。共用体只能存储其中一个成员变量的值,其他成员变量的值会被覆盖或无效。共用体也可以通过.运算符来访问或修改其成员变量的值。

        枚举是由一组有名字的整数常量组成的数据类型,它可以用来表示一些固定或有限的选项。枚举的每个常量都有一个默认或指定的整数值,枚举的总大小等于一个整数类型的大小。枚举可以通过其名字来访问或赋值其常量值,也可以通过强制类型转换来获取其整数值。

        在嵌入式系统开发中,枚举一般用于哪些地方?

        为固定的值命名,提高代码的可读性和可维护性。例如,为GPIO的输入输出模式、定时器的工作模式、串口的波特率等定义枚举值,使代码更加直观和清晰。

        作为数组访问的下标,方便管理数据。例如,为汽车故障诊断的PID参数、传感器的数据类型、协议的帧类型等定义枚举值,然后用枚举值作为数组的下标,可以快速地存取数据。

        作为函数参数或返回值,约束输入输出范围。例如,为中断处理函数、状态机函数、配置函数等定义枚举类型的参数或返回值,可以限制输入输出只能在枚举值的范围内,避免错误或异常。

        作为设置值或标志位,控制程序流程。例如,为系统的工作状态、错误类型、事件类型等定义枚举值,然后用枚举值作为设置值或标志位,可以控制程序的分支或循环。

        写一段代码片段本机器是大端还是小端? 

        我可以利用共用体(联合体)的特性来判断机器大小端,联合体中的不同成员共享同一块内存空间,因此可以通过访问不同类型的成员来判断字节的顺序。

#include <stdio.h>

// 定义一个联合体类型
union Test {
    int a; // 4字节
    char b; // 1字节
};

// 定义一个判断函数,返回1表示大端,返回0表示小端
int is_big_endian() {
    union Test t; // 创建一个联合体变量
    t.a = 0x01020304; // 给a赋值为16进制数
    if (t.b == 0x01) { // 如果b等于最高位字节
        return 1; // 表示大端
    } else { // 否则
        return 0; // 表示小端
    }
}

int main() {
    if (is_big_endian()) { // 调用判断函数
        printf("本机器是大端\n"); // 输出结果
    } else {
        printf("本机器是小端\n");
    }
    return 0;
}

排序算法

        各种排序算法的时间复杂度,最小与最大时间复杂度,空间复杂度,稳不稳定


        🍻各路大神,还有什么在笔试面试中遇到的问题欢迎补充说明,说不定下次文章更新中就有你提出的问题哦

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勾栏听曲_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值