【技术点】嵌入式技术考点一:C语言

07-11 1270阅读

文章目录

    • 1.数组和链表的区别是什么?
    • 2.什么是宏定义?有什么好处?
    • 3.关键字,以及各自的作用?
    • 4.什么是条件编译?.h 头文件中的 ifndef/define/endif 的作用?
    • 5.while和do while的区别?
    • 6.for和while的区别?
    • 7.什么是“内存对齐”?为什么要这样做?
    • 8.关键字 static 的作用是什么?
    • 9.#include 与 #include “file.h”的区别?
    • 10.描述实时系统的基本特性
    • 11.全局变量和局部变量在内存中有什么区别?
    • 12.堆栈溢出一般是由什么原因导致的?
    • 13.static全局变量与普通的全局变量有什么区别?
    • 14.局部变量能否和全局变量重名?
    • 15.全局变量可不可以定义在可被多个.C文件包含的头文件中?
    • 16.const与#define相比有何优点.
    • 17.几种内存分配方式以及它们的区别
    • 18.main函数执行以前还会执行什么代码?
    • 19.结构体(struct)与联合(union)的区别?
    • 20.sizeof和strlen的区别?
    • 21.一个频繁使用的短小函数,应该使用什么来实现?有什么优缺点?
    • 22.什么情况下用vector,什么情况下用list?
    • 23.C语言写个排序算法,并且说明其优缺点。
    • 24.头文件的作用时什么?
    • 25.C/C++程序 内存分布情况 常量所在的区?
    • 26.断错误出现的原因有哪些,如何避免这些问题?
    • 27.什么是大端存储,什么是小端存储?
    • 28.无符号16位整型数据的取值范围?有符号16位整型数据的取值范围?
    • 29.哪种排序最快,快速排序是如何实现的?
    • 30.C语言的关键字static和C++的关键字static有什么区别
    • 31.谈谈你对面向对象的认识?面向对象和面向过程的区别?

      1.数组和链表的区别是什么?

      数组:

      【技术点】嵌入式技术考点一:C语言
      (图片来源网络,侵删)
      • 一种线性数据结构,它由一组连续的内存空间组成,每个元素都可以通过下标来访问。
      • 数组访问元素非常快速,时间复杂度为O(1),但是插入和删除元素的效率较低,时间复杂度为O(n)。

        链表:

        • 一种非线性数据结构,它由一组节点组成,每个节点包含数据和指向下一个节点的指针。
        • 链表插入和删除元素非常快速,时间复杂度为O(1),但是访问元素的效率较低,时间复杂度为O(n)。

          总的来说,数组适合用于需要频繁访问元素的场景,而链表适合用于需要频繁插入和删除元素的场景。

          2.什么是宏定义?有什么好处?

          宏定义:

          • 是一种预处理指令,用于将一个标识符替换为一个特定的文本字符串。它通常用于定义常量、函数、条件编译等。

            好处:

            • 提高代码的可读性和可维护性:通过宏定义,可以将一些常量或者复杂的表达式定义为一个易于理解的名称,使代码更加通俗易懂。
            • 提高代码的可移植性:通过宏定义,可以将一些与平台相关的代码抽象出来,使代码更加具有通用性,从而提高代码的可移植性。
            • 提高代码的效率:通过宏定义,可以将一些频繁使用的代码片段定义为宏,从而减少代码的重复性,提高代码的执行效率。
            • 方便调试:通过宏定义,可以在代码中添加一些调试信息,方便调试人员进行调试。

              3.关键字,以及各自的作用?

              关键字:

              • C语言关键字共有32个,它们是:auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while。

                作用:

                • auto:用于定义自动变量,即在函数内部定义的变量。
                • break:用于跳出循环或switch语句。
                • case:用于switch语句中的分支。
                • char:用于定义字符类型变量。
                • const:用于定义常量,即不可修改的变量。
                • continue:用于跳过循环中的某次迭代。
                • default:用于switch语句中的默认分支。
                • do:用于do-while循环。
                • double:用于定义双精度浮点数类型变量。
                • else:用于if语句中的否定分支。
                • enum:用于定义枚举类型。
                • extern:用于声明外部变量或函数。
                • float:用于定义单精度浮点数类型变量。
                • for:用于for循环。
                • goto:用于无条件跳转到指定标签。
                • if:用于条件判断语句。
                • int:用于定义整型变量。
                • long:用于定义长整型变量。
                • register:用于定义寄存器变量,即建议编译器将变量存储在寄存器中。
                • return:用于从函数中返回值。
                • short:用于定义短整型变量。
                • signed:用于定义有符号类型变量。
                • sizeof:用于获取变量或类型的大小。
                • static:用于定义静态变量或函数。
                • struct:用于定义结构体类型。
                • switch:用于多分支选择语句。
                • typedef:用于定义新的类型名称。
                • union:用于定义联合体类型。
                • unsigned:用于定义无符号类型变量。
                • void:用于定义无返回值的函数或指针类型变量。
                • volatile:用于定义易变变量,即可能被意外修改的变量。 强制编译器每次从内存中取得该变量的值,而不是从被优化后的寄存器/缓存中读取。
                • while:用于while循环。

                  4.什么是条件编译?.h 头文件中的 ifndef/define/endif 的作用?

                  条件编译:

                  • 一种在源代码中根据条件选择性地包含或排除特定部分的编译技术。这些条件可以是预定义的宏、编译器选项、操作系统或硬件平台等。
                  • 通常用于处理不同的编译环境、版本控制、调试和优化等方面。
                  • 通常使用预处理指令(如#ifdef、#ifndef、#if、#elif、#else、#endif)来实现。

                    作用:

                    • 防止该头文件被重复引用。

                      5.while和do while的区别?

                      它们的区别在于循环条件的判断时机不同。

                      • while循环先判断循环条件,如果条件为真,则执行循环体,否则跳出循环。循环可能一次都不执行。
                      • do while循环先执行一次循环体,然后再判断循环条件,如果条件为真,则继续执行循环体,否则跳出循环。循环至少会执行一次循环体。

                        6.for和while的区别?

                        • for循环和while循环都是用来重复执行一段代码的,for循环适用于已知循环次数的情况,而while循环适用于不确定循环次数的情况。

                          7.什么是“内存对齐”?为什么要这样做?

                          1. 内存对齐:是按照成员的声明顺序,依次进行内存分配,其偏移量为成员大小的整数倍,0看做任何成员的整数倍,最后结构体的大小为最大成员的整数倍。
                          2. 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
                          3. 性能原因:为了访问未对齐数据的内存,处理器需要作两次内存访问;而对齐的数据内存访问仅需要一次内存访问。

                          8.关键字 static 的作用是什么?

                          1. 在函数体,一个被 static 声明的静态变量,在这一函数被调用过程中维持其值不变。
                          2. 在模块内(但在函数体外),一个被 static 声明的静态变量,可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
                          3. 在模块内,一个被 static 声明的静态函数,只可被这一模块内的其它函数调用。但不能被模块外其它函数访问。

                          9.#include 与 #include “file.h”的区别?

                          • 前者是从 Standard Library 的路径寻找和引用 file.h,而后者是从当前工作路径搜寻并引用 file.h。

                            10.描述实时系统的基本特性

                            • 在特定时间内完成特定的任务,实时性与可靠性。

                              11.全局变量和局部变量在内存中有什么区别?

                              • 全局变量储存在静态数据区,局部变量是存储在堆栈中。

                                12.堆栈溢出一般是由什么原因导致的?

                                1. 没有回收垃圾资源
                                2. 层次太深的递归调用

                                13.static全局变量与普通的全局变量有什么区别?

                                • 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
                                • 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。
                                • static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
                                • 另外static函数与普通函数的一个区别是:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

                                  14.局部变量能否和全局变量重名?

                                  • 能,局部会屏蔽全局。要用全局变量,需要使用"::"。

                                    15.全局变量可不可以定义在可被多个.C文件包含的头文件中?

                                    • 可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

                                      16.const与#define相比有何优点.

                                      1. const 常量有数据类型,而宏常量没有数据类型。编译器可以对const修饰的数据进行类型安全检查。而对宏常量只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。
                                      2. 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

                                      17.几种内存分配方式以及它们的区别

                                      1. 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
                                      2. 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令。
                                      3. 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。

                                      18.main函数执行以前还会执行什么代码?

                                      • 全局对象的构造函数会在main函数之前执行。

                                        19.结构体(struct)与联合(union)的区别?

                                        1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在,而且不同成员的存放地址不同。
                                        2. 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的

                                        20.sizeof和strlen的区别?

                                        1. sizeof是一个操作符,strlen是库函数
                                        2. sizeof的参数可以是数据类型也可是变量,而strlen只能以结尾为’\0’的字符串作参数
                                        3. 编译器在编译时就计算出sizeof的结果,而strlen必须在运行时才能计算出来
                                        4. sizeof技术按数据类型占内存大小,strlen计算字符串实际长度

                                        21.一个频繁使用的短小函数,应该使用什么来实现?有什么优缺点?

                                        使用内联函数进行实现。

                                        优点:

                                        • inline定义的内联函数,函数代码被放入符号表中在使用时进行替换(像宏一样)效率很高
                                        • 类的内联函数也是函数编译器在调用一个内联函数首先会检查参数问题,保证调用正确,像真正的函数一样消除了隐患及局限性
                                        • Inline可以作为类的成员函数,也可以使用在类的保护成员及私有成员

                                          22.什么情况下用vector,什么情况下用list?

                                          • vector拥有一段连续的内存空间,因此支持随机访问,如果需要高效的随机访问,而不在乎插入和删除的效率使用vector
                                          • List拥有一段不连续的内存空间,如果需要高效的插入和删除,而不关心随机访问使用list

                                            23.C语言写个排序算法,并且说明其优缺点。

                                            1. 插入排序:优点:稳定、快;缺点:比较次数不一定次数越少插入点数据移动越多
                                            2. 希尔算法:优点:快、数据移动少;缺点:不稳定
                                            3. 简单选择排序:优点:数据移动次数已知为(n-1)次;缺点:比较次数多
                                            4. 冒泡排序:优点:稳定;缺点:慢,每次只能移动相邻的两个数据

                                            24.头文件的作用时什么?

                                            • 通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进文件即可。用户只需要按照头文件中的接口声明来调用库功能而不必关心接口怎么实现的。
                                            • 头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声译器就会指出错议规则能大大减轻程序员调试、改错的负担。

                                              25.C/C++程序 内存分布情况 常量所在的区?

                                              区域:栈(Stack)、堆(Heap)、数据段(Data Segment)和代码段(Code Segment)

                                              • 栈(Stack):栈是用于存储局部变量、函数调用和函数参数等的区域。具有自动分配和释放内存的特性。
                                              • 堆(Heap):堆是用于动态分配内存的区域,通过malloc() 和 free() 或者 new 和 delete 进行管理。
                                              • 数据段(Data Segment):数据段是用于存储全局变量、静态变量和静态常量的区域。
                                              • 代码段(Code Segment):代码段是存储程序指令的区域,也称为文本段。

                                                26.断错误出现的原因有哪些,如何避免这些问题?

                                                1. 数组越界访问
                                                2. 指针悬空,指针指向已经释放的内存空间

                                                27.什么是大端存储,什么是小端存储?

                                                • 大端存储:高位字节(即最高有效位)被存储在内存的低地址处,而低位字节(即最低有效位)被存储在内存的高地址处
                                                • 小端存储:低位字节被存储在内存的低地址处,而高位字节被存储在内存的高地址处

                                                  28.无符号16位整型数据的取值范围?有符号16位整型数据的取值范围?

                                                  • 0 - 65535 -32768 – 32767

                                                    29.哪种排序最快,快速排序是如何实现的?

                                                    • 快速排序(Quick Sort)是一种效率较高的排序算法,其平均时间复杂度为O(nlogn)。
                                                    • 选取一个基准元素,将整个数组分为两个子数组,其中一个子数组的所有元素都小于等于基准元素,另一个子数组的所有元素都大于等于基准元素。然后对这两个子数组进行递归调用快速排序算法,直到子数组的长度为1或0,即达到排序的最终目标。

                                                      30.C语言的关键字static和C++的关键字static有什么区别

                                                      • C语言中的static:主要用于限定变量和函数的作用域,以及声明静态变量。
                                                      • C++语言中的static:除了限定作用域和声明静态变量外,还可以用于定义类的静态成员变量和静态成员函数。

                                                        31.谈谈你对面向对象的认识?面向对象和面向过程的区别?

                                                        • 面向对象:强调将系统中的实体抽象成对象,并通过对象之间的交互来完成系统的功能,具有封装、继承、多态等特性。
                                                        • 面向过程:强调将系统分解成一系列步骤和函数来解决问题,注重操作的处理过程。
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]