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

【面试】嵌入式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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/17220.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

九、MyBatis动态SQL

文章目录 九、动态SQL9.1 if9.2 where9.3 trim9.4 choose、when、otherwise9.5 foreach9.6 SQL片段 本人其他相关文章链接 九、动态SQL 9.1 if 总结&#xff1a;根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中。 User getUserByParamsWithIf(User user…

Packet Tracer - 在思科路由器上配置 AAA 认证

Packet Tracer - 在思科路由器上配置 AAA 认证 拓扑图 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 交换机端口 R1 G0/1 192.168.1.1 255.255.255.0 不适用 S1 F0/1 S0/0/0 (DCE) 10.1.1.2 255.255.255.252 不适用 不适用 R2 G0/0 192.168.2.1 255.2…

(四)Kubernetes - 手动部署(二进制方式安装)

Kubernetes - 手动部署 [ 3 ] 1 部署work node1.1 创建工作目录并拷贝二进制文件1.2 部署kubelet1.2.1 创建配置文件1.2.2 配置文件1.2.3 生成kubelet初次加入集群引导kubeconfig文件1.2.4 systemd管理kubelet1.2.5 启动并设置开机启动1.2.6 允许kubelet证书申请并加入集群 1.3…

JAVA-异常

文章目录 1.异常的体系1.3异常的分类 2.异常的处理2.2异常的抛出throw2.3异常的捕获2.3.1异常声明throws2.3.2 try-catch捕获并处理2.3.3 finally 2.4 异常的处理流程 3.自定义异常类 1.异常的体系 Throwable&#xff1a;是异常体系的顶层类&#xff0c;其派生出两个重要的子类…

人员拥挤检测系统 yolov5

人员拥挤检测系统通过YOLOv5网络模型算法技术&#xff0c;人员拥挤检测系统算法模型对校园/厂区车间/街道等场景的异常的人群聚集&#xff08;出现拥挤情况&#xff09;时&#xff0c;立刻抓拍存档并通知相关人员及时处理。在介绍Yolo算法之前&#xff0c;首先先介绍一下滑动窗…

ES是如何解决高可用

https://www.cnblogs.com/crazymakercircle/p/15433680.html ES是一个分布式全文检索框架&#xff0c;隐藏了复杂的处理机制&#xff0c;核心数据分片机制、集群发现、分片负载均衡请求路由。 ES的高可用架构&#xff0c;总体如下图&#xff1a; 说明&#xff1a;本文会以pdf…

Java 基础入门篇(一)—— Java 概述

文章目录 一、Java 概述二、Java 的产品 JDK2.1 JDK 安装2.2 Java与 Javac 介绍2.3 Java 程序的开发步骤 三、Java 程序的执行原理四、JDK 的组成五、Java 的跨平台工作原理 一、Java 概述 Java 是 sun 公司在 1995 年推出的一门计算机高级编程语言&#xff0c;其语言风格接近人…

深度学习卷积神经网络学习小结2

简介 经过大约两周左右的学习&#xff0c;对深度学习有了一个初步的了解&#xff0c;最近的任务主要是精读深度学习方向的文献&#xff0c;由于搭建caffe平台失败而且比较耗费时间就没有再尝试&#xff0c;所以并没有做实践方面的工作&#xff0c;本文只介绍了阅读文献学到的知…

外卖项目优化-02-mysql主从复制、读写分离(shardingJdbc)、Nginx(反向代理,负载均衡)

文章目录 瑞吉外卖项目优化-Day02课程内容前言1. MySQL主从复制1.1 介绍1.2 搭建1.2.1 准备工作1.2.2 主库配置1.2.3 从库配置 1.3 测试 2. 读写分离案例 (shardingJdbc)2.1 背景介绍2.2 ShardingJDBC介绍2.3 数据库环境2.4 初始工程导入2.5 读写分离配置2.6 测试 3. 项目实现读…

基于ATECLOUD的航电系统可灵活扩展自动化测试平台

随着电子技术的发展&#xff0c;航电系统在飞机整机中的重要性飞速提升。据统计&#xff0c;近年来航电系统在飞机出厂成本中的比例直线上升&#xff0c;航电系统研发成本已占飞机研制总成本的近30%&#xff0c;并保持着持续扩大的趋势。测试保障作为航电产业链至关重要的一环&…

基于JavaWeb实现的寻码网文章资讯管理系统

一、技术结构 前端&#xff1a;html ajax 后端&#xff1a;SpringBootMybatis-plus 环境&#xff1a;JDK1.8 | Mysql | Maven | Redis 二、功能简介 数据库与代码截图 后端管理-登录页 后端管理-首页 后端管理-文章管理-发布文章 后端管理-文章管理-文章列表 后端管理-文…

【iOS KVO(下) KVO的内部结构和源码】

前言 学习KVO的过程&#xff0c;我分为了KVO的实现过程分析和内部结构的学习&#xff0c;学习了实现过程&#xff0c;接下来看KVO是通过何种内部结构实现如此通知&#x1f4e2;和监听。 1 KVO的存储结构 KVO的实现过程离不开合理的存储结构&#xff0c;用到了如下几个类 GS…

智能安防系统-视频监控系统

一、智能安防系统 1、智能安防系统介绍 安全防范系统成为了智慧城市与物联网行业应用中的一个非常重要的子系统。 安防系统主要包括&#xff1a;视频监控系统、入侵报警系统、出入口控制系统、电子巡查系统以及智能停车场管理系统等5个子系统。 AI人工智能安防系统功能&#xf…

Java8中DateTimeFormatter真的是线程安全的吗?

文章目录 [toc] 1.背景2.解决办法2.1办法一&#xff1a;换姿势或者升级JDK的版本2.1办法二&#xff1a;更换文件名称字生成策略 Java8中DateTimeFormatter真的是线程安全的吗&#xff1f; 答案是否定的 1.背景 由于之前写了一个旷世的ocr的服务,接入了旷世的FaceID的人脸比对…

C++笔记——第十六篇 异常

目录 1.C语言传统的处理错误的方式 2. C异常概念 3. 异常的使用 3.1 异常的抛出和捕获 在函数调用链中异常栈展开匹配原则 3.2异常安全 4.异常的优缺点 1.C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序&#xff0c;如assert&#xff0c;缺陷&a…

04-Vue技术栈之组件化编程

目录 1、模块与组件、模块化与组件化1.1 模块1.2 组件1.3 模块化1.4 组件化1.5 传统方式编写应用1.6 组件方式编写应用 2、非单文件组件2.1 基本使用2.2 几个注意点2.3 组件的嵌套2.4 VueComponent2.5 一个重要的内置关系2.6 总结 3、单文件组件3.1 一个.vue 文件的组成(3 个部…

【玩转Git三剑客笔记】第一章 Git基础

第一章 Git基础 1.综述2.安装Git3.使用Git之前需要做的最小配置4.创建第一个仓库并配置local用户信息1.创建Git仓库2.设置Git最小配置 5.通过几次commit来认识工作区和暂存区1.将工作区中所有已经被git追踪的文件一起添加到暂存区2.git log查看提交日志 6.给文件重命名的简便方…

权限提升:不带引号服务路径 || 不安全的服务权限.

权限提升&#xff1a;不带引号服务路径 || 不安全的服务权限. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动…

探讨Redis缓存问题及解决方案:缓存穿透、缓存击穿、缓存雪崩与缓存预热(如何解决Redis缓存中的常见问题并提高应用性能)

Redis是一种非常流行的开源缓存系统&#xff0c;用于缓存数据以提高应用程序性能。但是&#xff0c;如果我们不注意一些缓存问题&#xff0c;Redis也可能会导致一些性能问题。在本文中&#xff0c;我们将探讨Redis中的一些常见缓存问题&#xff0c;并提供解决方案。 一、缓存穿…

了解MSIL汇编和IL汇编评估堆栈

.assembly extern mscorlib {}.assembly Test{.ver 1:0:1:0}.module test.exe.method static void main() cil managed{.maxstack 1.entrypointldstr "I am from the IL Assembly Language..."call void [mscorlib]System.Console::WriteLine (string)ret} 这是MSIL…