C语言常见面试题

本文详细探讨了C语言中的关键面试题目,包括static和const的作用、typedef与#define的区别、volatile关键字、sizeof与strlen的区别、堆栈差异、全局与局部变量、memcpy与strcpy的对比、段错误与内存泄漏的解释,以及函数指针、枚举和宏定义等核心概念。通过这些讲解,有助于准备C语言面试者深入理解语言特性和编程技巧。
摘要由CSDN通过智能技术生成
面试题:
  • 1.static和const的作用

static作用:

   静态型,可以修饰局部和全局变量,也可以修饰函数  (static int a = 3;)

1.存放全局区/静态区, .bss区(未初始化的全局变量和静态变量)和.data(初始化的全局变量和静态变量)

2.初始值默认为0,只初始化一次

3.限制作用域:修饰全局变量将变量限制在本文件中使用,修饰局部变量将变量限制在本函数中使用 

4.延长生命周期:修饰局部变量时,变量的生命周期为整个程序

const作用:

const是常量化的意思;

可以修饰变量,也可以修饰指针

当修饰变量的时候,因为不可以通过变量名对变量的值进行修改,所以在定义变量的时候需要给变量初始化,

当修饰指针的时候,const位置不同修饰的指针的指向或内容不能改变;

const int * p:指针指向的内容不能修改,指针的指向可以修改

int * const p:指针的指向不能修改,但是指针指向的内容可以修改

  • 2.typedef和define的区别

typedef:类型的重定义,可以对已有的类型重定义为新的类型名

define:宏定义,是在预处理阶段进行展开,不会检查代码错误;在代码中使用的时候注意是单纯的替换

详细解读:

1. 类型不同

在C语言中

typedef 是关键字,通常用来定义指针 、结构体等类型。

#define 是C预处理指令

2. 处理阶段不一样

typedef 在编译阶段处理。并且具有类型检查功能。

#define 在预处理阶段进行简单的替换,不会进行类型检查。

3. 功能不同

typedef 通常用于 类型定义,比如指针,数组,结构体等。方便记忆和使用。

#define 可以用于 变量定义,编译开关 ,变量和常量。

4. 作用域不同

typedef 具有自己的作用域

#define 没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。如果需要解除掉之前声明的宏定义 。

可以使用 #undef name,这个命令使预处理器忘记name的所有宏定义。

5 对指针的操作

二者修饰指针类型时,作用不同

  • 3.volatile作用(关键字)

防止编译器优化。volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。

  • 4.sizeof和strlen区别

1.sizeof是关键字;strlen是函数

2.sizeof是用来计算数据所占空间大小;strlen用来计算字符串的实际长度

3.sizeof是包括\0的;strlen不包括\0。当省略字符数组长度时,sizeof比strlen大1。

  • 5.数组和链表的区别

数组

链表

数组是一个相同数据类型的数据集合

链表是一个有相同数据类型的续集,

其中每个元素使用指针链接

数组元素可以使用数组索引随机访问

链表不允许随机访问,元素只能

被有序或顺序访问

数组的元素在内存中连续存储

元素可能存读在内存的任意地方,链表创建

一个指针向相应的数据

插入和删除操作非常耗时,时间为O(n),因为元素的内存地址是连续和固定的

链表的插入和删除操作非常快,时间为O(1)

数组的内存是静态分配的,在编译期间完成

链表的内存分配是动态的,在运行时动态分配

数组的大小必须在数组的声明中或初始化的时间指定

链表的大小随着元素的插入或删除变化

  • 6.对指针的理解

指针就是地址,指针变量就是存放地址的变量;指针可以使用简单的运算符操作;指针加一,代表指向下一个元素;对于32位系统,指针占4字节

  • 7.结构体和共用体区别

二者都是构造数据类型

1)结构体:让C语言实现面向对象的思想。结构体使用的时候,结构体中每一个成员都有自己的内存空间,计算结构体大小指的是所有成员的总字节大小,要注意内部字节对齐;首地址对齐(按最大)、总大小对齐(按最大)、成员对齐(按成员类型)

2)共用体又叫联合体,每一个成员都共享内存空间。因此,共用体大小等于成员中占内存最大的那个大小。

  • 8.结构体字节对齐

1) 首地址对齐:结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2)成员类型对齐:结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

3)总大小对齐:结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。

第一条:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值