2023最新C语言经典面试题汇总

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

写出Bool、int、指针变量、float与“零值”比较的if语句

Bool型

if(flag)、if(!flag)

int型

if(flag == 0)、if( flag!= 0)

指针变量

if(p == NULL)、if( p!= NULL)

float型

const float EPSINON = 0.0001; if( (x >= -EPSINON) && (x <= EPSINON));

设置地址未为0x67a9的整型变量的值为0xaa66

int *prt;
ptr = (int *)0x67a9;
*ptr = 0xaa66;
*(int *)0x67a9 = 0xaa66;

要对绝对地址赋值我们可以用(unsigned int*)0x10000=1234那么要想程序跳转到绝对地址是0x10000去执行应该怎么做

先强制转换成函数指针(void(*)())0x10000;

再调用它*( ( void(*)( ) )0x10000 )();

描述一下gcc的编译过程

gcc编译过程分为4个阶段预处理、编译、汇编、链接

预处理进行头文件、宏定义的替换条件编译删除注释还有语义和词义的分析

编译将预处理后的文件编译成汇编文件

汇编将汇编文件转换二进制文件

链接将二进制文件链接成可执行文件

#include< >和#include" "的区别

#include< >是到系统指定目录下寻找文件

#include" "是先到用户指定的目录下寻找文件找不到就到系统指定目录下寻找

头文件中的ifndef/define/endif 干什么用

防止头文件被重复引用。

有符号与无符号的区别

有符号的数据最高位为符号位0表示正数1表示负数

无符号的数据最高位不是符号位只是数据的一部分。

sizeof与strlen的区别

sizeof是操作符参数可以是数据类型也可以是变量在编译时就已经计算出来sizeof的结果计算的是数据类型占内存的大小

strlen是库函数参数只能是以‘\0’结尾的字符串需要在运行时才能计算出来计算的是字符串的长度

嵌入式系统中经常要用到无限循环你怎么样用C编写死循环

while(1)
{}
for(;;)
{}
loop: ···
goto loop;

宏定义

写一个标准宏MIN

#define MIN(x,y) ( (x)<=(y)? (x):(y) )

用预处理指令#define声明一个常数用以表明1年中有多少秒忽略闰年问题

#define SEC_YEAR (365 * 24 * 60 * 60)UL

用宏定义写出swapxy即交换两数

#define swap(x,y) x=x+y;y=x-y;x=x-y;

已知一个数组table 用一个宏定义求出数据的

#define LENGIH sizeof(table)/sizeof(table[0])

关键字

关键字static的作用是什么

  1. 修饰局部变量时变量只执行一次存在于静态存储区不初始化内容为0只在当前语句块有效程序结束后才释放。

  2. 修饰全局变量时变量存在于静态存储区不初始化内容为0只在当前文件有效程序结束后才释放。

  3. 修饰函数时该函数只能在当前文件中使用。

static函数与普通函数的区别与好处

static修饰的函数只能在当前文件使用

普通函数可以被外部文件用extern调用

用static修饰函数的好处是

  1. 其他文件可以定义相同名字的函数

  2. 该函数不能被其他文件调用

static修饰变量的作用与好处

修饰局部变量存在于静态存储区补初始化内容为0作用域在当前函数/语句块

修饰全局变量存在于静态存储区不初始化内容为0作作用域只在当前文件

用static修饰变量的好处是

  1. 其他文件可以定义相同名字的变量

  2. 该变量不能被其他文件调用

关键字volatile有什么含意并给出三个不用的例子

volatile指的是易变的。 用以告诉编译器被volatile修饰的变量随时可能被改变。

以下场合需要用到volatile修饰

  1. 中断服务程序中修改的供其他程序检测的变量

  2. 多任务环境下共享的标志

  3. 存储器映射的硬件寄存器

关键字 _interrupt

_interrupt是用来定义中断服务子程序ISR的它有以下几个特点

  1. ISR不能返回一个值

  2. ISR不能传递参数

  3. 最好不要做浮点运算

  4. 最好不要加打印

关键字const有什么含义

const代表着只读让编译器去保护那些不希望被改变的参数。

  1. 定义变量变量的值不能被改变

  2. 定义指针指针的值不能被改变

  3. 定义类的成员函数成员函数不能改变类的变量

以下代码声明的含义是什么

  1. const int a;

  2. int const a;

  3. const int *a;

  4. int* const a;

  5. const int* const a;

  1. a是一个常数整数

  2. a是一个常数整数

  3. a是一个指向常数整数的指针指针的值不可修改但是指针可以修改

  4. a是一个指向整数的常量指针整数的值可以修改但是指针不可修改

  5. a是一个指向const整数的const指针整数和指针的值都不可以修改

c和c++ 中的struct有什么不同

  1. C中的struct不能有成员函数而C++的struct可以。

  2. C中struct的默认权限是public而C++的struct是private。

内存

内存最小存储单元以及内存最小计量单元是什么

内存最小存储单元是Bit二进制位

内存最小计量单元是Byte字节

描述一下内存分区

程序在运行前代码区、BSS段为未初始化数据区、data段初始化数据区

程序在运行后堆区、栈区、全局区静态区、代码区、文字常量区。

stack栈与heap堆的区别

stack栈由系统自动分配其地址和容量是系统定的是一块连续的内存Window下是2M

heap堆是用户自己用malloc申请的char p = (char)malloc()它是不连续的。

malloc()与new()的区别

  • malloc

  1. 是在堆中申请内存申请需要指定大小

  2. 返回void*类型需使用强制转换

  3. 失败返回NULL

  • new

  1. 是在自由存储区申请内存无需指定大小

  2. 返回对象类型指针无需转换安全

  3. 失败返回mac_alloc异常

内存溢出一般是由什么导致的

  1. 动态申请的空间没有回收

  2. 数组越界访问

变量

变量的命名规则

变量名由字母、数字、下划线组成但是不能以下划线开头。

变量的声明和定义有什么区别

变量的定义需要定义存储空间

变量的声明不需要建立存储空间。

描述普通局部变量、普通全局变量、静态局部变量、静态全局变量的区别

普通局部变量存在于栈区不初始化内容随机只作用于当前语句块语句块结束变量空间释放。

普通全局变量存在于全局区不初始化内容为0作用于当前文件也能被其他文件用extern调用进程结束变量空间才被释放

静态局部变量存在于静态存储区不初始化内容为0作用于复合语句进程结束变量空间才被释放

静态全局变量存在于静态存储区不初始化内容为0只作用于当前文件进程结束变量空间才被释放。

用变量a进行定义

  • 一个整型数

int a

  • 一个指向整型数的指针

int *a

  • 一个指向指针的指针它指向的指针是指向一个整型数

int **a

  • 一个有10个整型数的数组

int a[10]

  • 一个有10指针的数组该指针是指向一个整型数

int *a[10]

  • 一个指向有10个整型数数组的指针

int (*a)[10]

  • 一个指向函数的指针该函数有一个整型数参数并返回一个整型数

int (*a)(int)

  • 一个有10个指针的数组该指针指向一个函数该函数有一个整型数参数并返回一个整型

int (*a[10])(int)

如何定义一个已经引用过的全局变量

  1. 头文件定义

  2. extern调用

数组

数组的特点

  • 所有成员都是相同的数据类型

  • 所有成员再内存中地址是连续的

数组的分类

数组的分类有静态数组、动态数组。

静态数组在程序运行前就确定了大小且运行中大小不能更改。

动态数组主要是在堆中申请的空间大小在运行中确定且可以更改。

一维数组在不初始化、部分初始化、完全初始化的区别

不初始化如果是局部数组内容随机如果是全局数组内容为0

部分初始化未初始化的部分自动补0

完全初始化数组大小由初始化的个数确定。

数组作为类型、作为地址、取地址的区别

数组作为类型代表整个数组的大小

数组作为地址代表数组首元素地址

数组取地址代表数组首地址。

二维数组在物理和逻辑上的区别

在物理上是一维的在逻辑上是二维的。

函数

函数的定义与函数的声明有何区别

函数的定义指的是对函数功能的确立包括函数类型、函数名、形参、函数体。

函数的声明告诉编译器这个函数的类型、名字、形参。

宏函数的概念以及作用

把一些短而小、使用频繁的函数写成宏函数

由于宏函数没有普通函数的压栈、跳转、返回等开销可以提高代码效率。

指针

描述一下32位或64位平台下指针的大小

32位平台任意类型的指针大小为4字节

64位平台任意类型的指针大小为8字节

指针数组的概念

本质是一个数组数组中的每一个元素都是一个指针。

使用realloc给已分配的堆区空间追加空间时需要注意什么

用指针变量保存realloc的返回值。

什么情况下会出现野指针

  1. 指针未初始化

  2. 指针释放后未置空

  3. 指针操作超出其作用域

引用与指针的区别

  1. 引用必须初始化指针不必初始化

  2. 引用初始化用不能被改变指针可改变

  3. 引用不可指向空值指针可指向空值

指针作为函数参数的输入特性和输出特性

输入特性主函数分配空间被调函数使用空间

输出特性被调函数分配空间主函数使用空间。

(void )ptr 和((void**))ptr 的结果是否相同其中ptr为同一个指针

一样的。

结构体

结构体和共用体的区别是啥

结构体的成员拥有独立的空间

共用体的成员共用一块空间并且成员能访问的口昂见大小由成员自身类型决定。

如何理解结构体的浅拷贝和深拷贝

当结构体中出现指针成员的时候容易出现浅拷贝和深拷贝的问题。

浅拷贝两个结构体的指针成员指向同一块区域空间结构体释放时这块空间会被多次释放

深拷贝两个结构体指针成员指向不空的区域空间只是内容拷贝一份结构体释放时不会出现同一个空间被释放多次的情况。

文件

文件缓冲的几个刷新方式

  • 行缓冲

  • 满缓冲

  • 强制缓冲

  • 关闭缓冲

谈谈文件的分类

文件分为二进制文件和文本文件。

二进制文件基于值编码需要根据具体的应用才能知道某个值的意思

文本文件基于字符编码一个字节一个意思可以通过记事本打开。

进程

进程通信IPC的方式

  1. 管道pipe/fifo

  2. 消息队列

  3. 共享内存

  4. 套接字socket

  5. 信号

  6. 信号量

字节对齐

代码

*ptr++ 、++ptr和++ptr相同吗

ptr++等价于ptr++

++ptr等价于++ptr

++ptr等价于++ptr

请问以下代码有什么问题

int main()
{
char a;
char *str=&a;
strcpy(str,"hello");
printf(str);
return 0;
}

没有给str分配空间将一个字符串支复制给一个字符变量指针将会发生异常因为越界读写导致系统崩溃。 正确修正方法

char a[10]; char *str = a;

以下代码有什么出错的地方

char* s="AAA";
printf("%s",s);
s[0]='B';
printf("%s",s);

编译正确运行错错误“AAA”是字符串常量s[0]试图修改字符串常量的指值字符串常量不能修改。

以下代码有什么出错的地方

wap( int* p1,int* p2 )
{
int * p;  //(int)malloc(4); is ok
*p = *p1;
*p1 = *p2;
*p2 = *p;
}

没有给指针p分配空间为空指针无法存储指针p1的值。

编写memcpy函数

void* memcpy(void* dest,const void* src,int size)
{
  if(dest == NULL || src == NULL)
      return dest;
  while(size--)
  {
      *(char*)dest = *(char*)src;
      dest = dest+1;
      src = src+1; 
  }
  retern dest;
}

编写strcpy函数并解释为什么要返回char型

char* strcpy(char* strDest,const char* strsSrc)
{
  if(strDest == NULL || strSrc == NULL)
    return NULL;
    
    char*p = strDest;
    
    while(*strsSrc != '\0')
    {
        *p++ = *strsSrc++;
    }
    *p = *strSrc;
    return strdDest;
}

返回char类型是为了增加灵活性比如链式操作例如

int length = strlen( strcpy(str,"Hello World") );

小结

我记得曾经有人说过思想和行动的区别在于

想谈恋爱却高呼自由可贵想进大厂却不想工作想当大牛却不想学习每个人都知道明天必须披荆斩棘的活下去却依旧浑浑噩噩的度过今天。

不用去怀疑自己的能力你只需要一份靠谱的学习资料一个学习的deadline以及一个没学完就打爆你狗头的人很快你就会被自己的才华和能力所惊艳。

我收集了一些linux的资料算法小抄和计算机基础的资料。

以下资料仅供个人学习使用欢迎大家一起学习探讨。

linux保姆级教程完整版文档资料

希望以上内容能帮助到你祝各位生活愉快。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6