【面试】嵌入式C语言题目整理

  1. 描述内存四区。

内存四区分为:代码区、静态区、堆区、栈区
代码区就是用来存放代码的。
静态区用来存放全局变量、静态变量、常量(字符串常量、const修饰的全局变量)。
堆区中的内存是由程序员自己申请和释放的,用malloc函数去申请,用free释放内存。
栈区中的内存是由编译器自动申请和释放的,用来存放函数返回值、函数参数、局部变量等。

  1. new和malloc的区别

new和malloc都是用于动态的内存分配。
new是适用于C++申请内存分配,malloc在C和C++中都适用。
new自动计算分配内存大小,malloc需要手动计算内存大小,并以参数形态传入。也就是所new是根据类型申请的空间,malloc是根据输入的大小计算的内存空间。
new返回值是申请类型的指针,malloc返回类型是void*,需要强制转换。

  1. 数组与指针的区别

类型不同:数组是一种复合类型,它是由相同数据类型的元素组成的序列;指针是一种基本类型,它是一个指向某种类型地址的变量。
大小不同:如果用sizeof去求解占用内存大小的话,数组是全部元素实际占用的内存大小;而指针占用内存的大小与其指向类型无关,是固定的,例如在32位平台下,是固定的4字节。
内存布局不同:数组是一段连续的内存地址空间,而指针是指向某个存储位置的变量。
访问方式不同:数组可以通过下标来访问其中的元素,数组名可以当作指针使用,通过加加减减以及解引用的方式访问元素。

  1. 野指针

定义的指针未初始化;
释放地址后的指针,未重新执行新的地址或者NULL;
指针运算过程中越界;

  1. static关键字

静态局部变量:只有当该变量所在的函数第一次被调用的时候,静态局部变量才会被初始化;当以后在进入该函数时,该变量不会再被初始化,仍旧保留上一次退出该函数时的值。
静态全局变量:只能被初始化一次,并且该变量的作用域只能是当前c文件。
静态函数:该函数只能被当前c文件调用,不可以被其他文件调用。

  1. gcc的编译过程

预处理、编译、汇编、链接

  1. 指针常量与常量指针

指针常量:int* const a; 该指针变量是不能变的,即存储的地址是不能变的,但是该地址指向的值是可以变化的。
常量指针:const int* a; 该指针变量是可以变化的,即存储的地址是可以变化的,但是地址指向的值是不能变化的。也就是说当a指向了一个地址之后,该地址中的值是不能通过a来改变的。

  1. #include<> 与#include ""的区别?

#include<>会去系统指定目录查找头文件。
#include ""会先在项目目录中查找头文件,如果没有的话,再去系统指定目录中查找。

  1. #define与typedef的区别

#define是预处理中的宏定义命令,在预处理阶段进行简单的字符替换,并不进行正确性检查。
typedef是关键字,常用于替换复杂类型声明定义的简单别名,在编译阶段是进行正确性检查的。
#define不需要;结尾,typedef需要;结尾
对指针的控制不同,如下:

这种定义方式,t和tt都是int*类型,而d和a是int*,dd和aa是int。

  1. ifndef/define/endif的作用

避免头文件被重复引用

  1. extern关键字

c语言在定义变量或者函数的时候,默认是前面加了extern关键字。
表明该变量或者函数能够被其他文件所使用。

其他文件在使用的时候,需要用extern来声明所使用的变量或函数,表示该变量或函数需要去其他文件中查找。

  1. volatile关键字

volatile是c语言的关键字,作用是防止编译器被优化。
编译器优化的意思是,因为cpu的执行速度比内存的读取速度要快的多,某些变量可能会被存放在寄存器中,当cpu需要读取该变量时,就直接从寄存器读取(而不是去该变量的实际内存地址读取),提升了程序运行速度。
假如某个函数将该变量的值改变了,但是并未触发寄存器更新,那么cpu读取出来的值与实际值就会发生不一致。
所以需要vloatile关键字修饰变量,禁止编译器对其进行优化。
比如说:
中断服务程序中修改的供其它程序检测的变量需要加volatile。
被多个线程共享的变量需要加volatile。

  1. sizeof和strlen的区别

sizeof是关键字;strlen是函数
sizeof可以计算任何类型的实际内存占用大小;strlen只能计算字符串的实际长度。
sizeof是在编译时计算大小的;strlen是在运行期确定字符串长度的。

  1. 字节对齐

C语言结构体字节对其规则简述

  1. 结构体与联合体的区别

结构体中的每一个成员的内存都是独立的,对某个成员赋值,并不会影响其他成员的内容。
联合体(共用体)中的成员间的内存是共用的,对某个成员赋值,会破坏掉其他成员的值,也就是说在同一时间,只能有一个成员的值是有效的。
再说一下,注意事项:①无论是结构体还是共用体,计算占用内存大小时,都需要考虑字节对齐规则;②讲解一下共用体在自己项目中的应用。

  1. 短路求值问题

if( (语句1) || (语句2) ) 假如语句1已经判断为真了,那么if肯定为真,语句2就不会再执行了;
if( (语句1) && (语句2) ) 假如语句1已经判断为假了,那么if肯定为假,语句2就不会再执行了;

  1. 指针数组与数组指针

指针数组:定义方式:int *p[5];表示该数组中的每一个元素都是指针类型。
数组指针:定义方式:int (*p)[5];表示该指针指向了一个长度为5的int类型的数组。例如二维数组的每一行,可以用数组指针来表示。

  1. 一维数组的数组名a、二维数组的数组名b的含义

一维数组的数组名表示第一个元素的地址,即a、a+1、a+n表示第1,2,…,n的元素地址。
对一维数组的数组名取地址,表示的是该数组的数组指针。
二维数组的数组名表示第一行数组的数组指针,即b、b+1、b+n、表示第1,2,…,n行数组的数组指针。

 int array[3] = { 1,2,3 };int(*p)[3]=NULL; //数组指针int* d=NULL;    //整型指针p = &array;   //取数组的地址d = array;   //第一个元素的地址printf("%d",*(*p+1));printf("%d",*(d+1));
 int a[2][3] = { {1,1,1},{2,2,2}};int(*p)[3]=NULL; //数组指针p = a;      //p此时为第一行数组的数组指针p = a + 1;  //p此时为第二行数组的数组指针printf("%d",*(*p+1));
  1. 不使用第三个变量,交换两个变量的值
 int a = 3, b = 5;a = a + b;b = a - b;a = a - b;printf("%d,%d\r\n",a,b);a = a ^ b;b = a ^ b;a = a ^ b;printf("%d,%d\r\n", a, b);
  1. 求1000以内的质数(素数)

除了1和它本身以外,不再有其他的因数。

int main()
{//打印出1000以内的质数int temp = 1;int count = 0;int flag = 0;while ((temp++) < 1000){flag = 0;for (int i = 2; i <= temp / 2; i++){if (temp % i == 0){flag = 1;break;}}if (flag == 0){printf("%d\r\n", temp);count++;}}printf("一个有%d个质数\r\n",count);
}
  1. 冒泡算法
void swap(int *a,int *b)
{*a = *a + *b;*b = *a - *b;*a = *a - *b;
}void sort(int* temp,int length)
{for (int i = 0; i < length-1;i++){for (int j=0;j<length-1-i;j++){if (*(temp + j) > *(temp + j + 1)){swap(temp + j, temp + j + 1);}}}
}
  1. 描述浅拷贝与深拷贝

当结构体中有指针存时,浅拷贝仅仅是将指针变量的值拷贝过来,而深拷贝是将指针指向地址中的值重新拷贝到另一个地址中,并指向。
比如:
例如结构体A中有指针int *p,指向了int x = 5。
浅拷贝到结构体B,那么B中的指针int *p存放的也是x的地址。
深拷贝到结构体C,会重新的找一个int类型的地址,将5这个值放进去,然后再用结构体C中的int *p指向它。
对于浅拷贝,假如A中p指向的x变为了6,那么B中的p指向的值也就变为了6。
对于深拷贝,假如A中p指向的x变为了6,而C中p指向的地址不再是x,所以C中p指向的值仍旧是5。

【面试】嵌入式C语言题目整理相关推荐

  1. 【面试题】某司社招面试题目整理及答案

    某司社招面试题目整理及答案 Java基础部分 HashMap的实现原理 如何解决Hash碰撞 HashMap的存储(hash算法.hash冲突.初始化.扩容) HashMap和HashTable的区别 ...

  2. 【面试】网易游戏面试题目整理及答案(1)

    网易游戏面试题目整理及题目(1) Python部分 计算机网络 参考资料 Python部分 迭代器生成器,生成器是如何实现迭代的? 答:迭代器iterator:迭代器就是实现了迭代方式的容器,iter ...

  3. 小米公司2021秋招面试题目整理

    [推荐阅读] 小米嵌入式软件工程师笔试题目解析 大疆笔试题目解析 岗位:嵌入式软件工程师(相机驱动岗).面试时间:40分钟. 以下问题面试者全部答出,已offer,薪资请去小程序offershow上查 ...

  4. 【面试】网易游戏面试题目整理及答案(5)

    网易游戏面试题目整理及答案(5) 算法 操作系统 Linux部分 其他 参考资料 算法 Leetcode 75题:请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征: 1)每一行 ...

  5. 重庆工商大学c语言实验一答案,重庆工商大学嵌入式实验考试题目答案 - 副本.doc...

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsp嵌入式开发 重庆工商大学嵌入式实验考试题目答案 - 副本.doc ...

  6. 各公司 Java 面试题目整理(基础+高级+算法+数据库)

    包含 Java 面试的各个方面,史上最全,苦心整理最全 Java 各公司面试题目整理包括但不限于基础+高级+算法+数据库优化+算法优化,使用层面广,知识量大,涉及你的知识盲点.要想在面试者中出类拔萃就 ...

  7. 面试篇1:嵌入式C语言面试常见问题

    嵌入式C语言面试常见问题 入门C语言20问20答: 01源程序的编译及链接是怎样一个过程? 02编写第一个简单的C语言程序 03C语言是强类型的语言,这是什么意思? 任何程序都要处理数据,计算机可以处 ...

  8. 【面试】网易游戏面试题目整理及答案(3)

    网易游戏面试题目整理及答案(3) 数据库部分 MySQL 事务 MySQL锁机制 MySQL调优 MySQL分区.分表.分库 主从复制 其他问题 数据库部分 MySQL 事务 事务的隔离级别有哪些?M ...

  9. 嵌入式软件工程师面试题目整理(一)

    文章目录 嵌入式软件工程师面试题目整理(一) Arm有多少32位寄存器? Arm2440和6410有什么区别 CPU,MPU,MCU,SOC,SOPC联系与差别 上拉&下拉&高阻态 串 ...

最新文章

  1. python空值填充为固定值_Python基础:numpy中空值怎样设置
  2. html语言的空格键,如何在如何在HTML中插入空格中插入空格
  3. Hierarchical Attention Networks for Document Classification(HAN)
  4. 谈谈我对Promise的理解
  5. Java设计链表(不带头结点的单链表)
  6. JDK9的安装与配置
  7. 【转】基于nginx + lua实现的反向代理动态更新
  8. Spring Cloud Alibaba之服务治理Nacos
  9. 禅道二次开发(一):开发环境配置
  10. python 四象限图_如何快速绘制出四象限图?
  11. C/C++中va_start/va_arg/va_end函数源码文件位置及实现原理
  12. 安卓P 自动调节亮度打开的状态下,手动拖动亮度条后,自动调节亮度失效
  13. c++中冒号(:)和双冒号(::)的用法
  14. 1134. 积木分发
  15. 【Nav2中文网】十一、迁移指南 (四)Galactic到Humble
  16. kafka安装(windows版)
  17. mac下charles抓包iPhone手机
  18. App Store 热搜页面被乱码攻占,腾讯成为唯一幸存者
  19. “互联网+”大学生创新创业大赛总决赛清华大学夺冠
  20. Unity的新动画系统(animator)在脚本中的操控

热门文章

  1. Java学习-使用文本编辑器编辑Java源代码
  2. win10系统dns错误如何解决【系统天地】
  3. 来一份Android动画全家桶(下篇)
  4. 如何将明细数据关联对照表后生成汇总统计表
  5. MySQL统计数据库所有表的数据量
  6. 移动设备的能源,未来无处不在
  7. (day2-spring和mybatis学习)-->重点增删改查
  8. 初识linux之shell外壳与基本权限
  9. Quagga编译安装
  10. TensorFlow性能分析调研