查找包含关键字的数据,返回值用逗号分开?

笔者最近在找工作,因此对应聘C/C++嵌入式开发工程师容易被问到,或者经常搞不清楚的问题做一个汇总,也希望能对找工作的小伙伴起到帮助参考的作用。本篇集中于C语言方面的面试题目。

因为是自己总结的,可能会存在错误,还烦请各位读者批评指正。


1. 一个由C/C++编译的程序占用的内存分为以下几个部分:

①栈区 —— 局部变量 —— 向低地址生长 —— 自动释放 —— 其操作方式类似于数据结构中的栈。

②堆区 —— 向高地址生长 —— 手动分配、释放的存储区 —— malloc,free —— 它与数据结构中的堆是两回事,分配方式倒是类似于链表

③全局/静态存储区static —— 全局变量,静态变量,程序运行结束后自动释放

④常量存储区const —— 常量字符串储存在这里。储存在常量区的只读不可写。程序运行结束后自动释放

⑤代码区 —— 存放函数体的二进制代码。

  • 静态内存分配:编译时分配,包括:全局、静态全局、静态局部
  • 动态内存分配:运行时分配:包括:栈(局部变量),堆(C语言常用到的变量被动态地分配到内存当中:malloc,calloc,realloc,free函数)

——> const修饰的全局变量也储存在常量区

——> const修饰的局部变量依然在上。

2. 存储类(内存管理):


①栈:局部变量,函数调用传参的过程。
②堆:动态存储区,需要程序员去申请释放
③数据段(data段):显式初始化仅非零的全局变量

(1)static修饰局部变量(静态局部变量)与普通局部变量相比:
① 静态局部变量作用域与连接属性,和普通局部变量一样
② 存储类:静态局部变量分配在data/bss段普通局部变量在栈上
③ 生命周期:因为存储类的不同,静态局部变量生命周期变长了,直到程序结束

——所以当静态局部变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能够再对它进行访问,直到该函数被再次调用,并且值不变。

(2)static修饰的全局变量or函数与普通的相比:
① 存储类、生命周期、作用域都一样
static修饰的全局变量的连接属性是内连接,普通的是外连接
即:static修饰的全局变量不能给文件调用——这也是静态变量和全局变量的区别。

对于局部变量来说,声明存储类型的作用是指定变量存储的区域(静态存储区或动态存储区)以及由此产生的生存期的问题

对于全局变量来说,由于都是在编译时分配内存,都存放在静态存储区,声明存储类型的作用是变量作用域的扩展问题。

1. 变量类型:是对数据分配存储单元的安排,包括存储单元的长度,及数据的存储形式

2. 内部函数:只能被本文件中的其他函数调用。定义内部函数时,在函数名、函数类型前加static。

外部函数:可供其他文件调用。定义外部函数时,在函数首部左端加上extern。若定义函数时省略extern,则默认为外部函数。

3. 因为A、B、C是外部变量

所以调用max函数时用不到参数传递,即在max函数中可以直接使用外部变量A、B、C的值

(这一点与局部变量有个实参传给形参的过程不同)

栈(操作系统):由操作系统(编译器)自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放。

堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

堆(数据结构):堆可以被看成是一棵树,如:堆排序。

栈(数据结构):一种先进后出的数据结构。

1. 串值的存储空间可在程序执行过程中动态分配而得。

2. 根结点是没有双亲的,所以我们约定根结点的位置域为-1.

3. 链表翻转(迭代法)

cur = tmp;//把之前下一个的值给当前位置

1. *在不同的场景下有不同的作用

*可以用在指针变量的定义中,表明这是一个指针变量,以和普通变量区分开;

*也可以在使用指针变量时,在变量前面加上,表示获取指针指向的数据,或者说表示的是指针指向的数据本身。

意义完全不同。以下面的语句为

第1行代码中*用来指明 p 是一个指针变量,第2行代码中*用来获取指针指向的数据。

需要注意的是,给指针变量本身赋值时不能加*。修改上面的语句:

第2行代码中的 p 前面就不能加*

指针变量也可以出现在普通变量能出现的任何表达式中,例如:

py = px; //把一个指针的值赋给另一个指针

2. 如果已执行“p=&a;”,即指针变量p指向了整型变量a,则:

其作用是:以整数形式输出指针变量p所指向的变量的值,即变量a的值。

3. 当数组作为函数的参数传递时,数组就自动退化为同类型指针。

1.数据类型:const修饰的变量有明确的类型,而宏没有明确的数据类型

2.安全方面:const修饰的变量会被编译器检查,而宏没有安全检查

3.内存分配:const修饰的变量只会在第一次赋值时分配内存,而宏是直接替换,每次替换后的变量都会分配内存

4.作用场所:const修饰的变量作用在编译、运行的过程中,而宏作用在预编译中

5.代码调试:const方便调试,而宏在预编译中进行所以没有办法进行调试。

—— const关键字的作用:

1. const 是定义只读变量的关键字,或者说 const 是定义常变量的关键字。
说 const 定义的是变量,但又相当于常量;说它定义的是常量,但又有变量的属性,所以叫常变量。用 const 定义常变量的方法很简单,就在通常定义变量时前面加 const 即可,如:

const 和变量类型 int 可以互换位置,二者是等价的,即上条语句等价于:

那么用 const 修饰后和未修饰前有什么区别呢?它们不都等于 10 吗?、

  • 用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。所以说它定义的是只读变量。这也就意味着必须在定义的时候就给它赋出值。
  • 如果定义的时候未初始化,我们知道,对于未初始化的局部变量,程序在执行的时候会自动把一个很小的负数存放进去。这样后面再给它赋出值的话就是“改变它的值”了,即发生语法错误。

上面定义了两个指针p1和p2。

在定义1中const限定的是*p1,即其指向空间的值不可改变,若改变其指向空间的值如*p1=20,则程序会报错;但p1的值是可以改变的,对p1重新赋值如p1=&k是没有任何问题的。

在定义2中const限定的是指针p2,若改变p2的值如p2=&k,程序将会报错;但*p2,即其所指向的值可以改变,如*p2=80是没有问题的,程序正常执行。

const常量会在内存中分配??

三种参数传递的方式:传值、传指针、传引用

形参的存储空间是函数被调用时才分配的

  • 引用是别名,指针是地址(实体)

引用一旦与某个对象绑定后就不再改变了

5. 进程和线程的区别?

进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。

线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位。

一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。

#include :到保存系统标准头文件的位置查找头文件。

#include" ":查找当前目录是否有指定名称的头文件,然后再从标准头文件目录中查找。

每个递归必须至少有一个条件,其满足时递归便不再运行,即:此时不再引用自身,而是返回值退出。

9. 各种数据类型的长度

2. 一个int占4个字节,sizeof就是4。在32位系统上,对任意指针求sizeof得到的结果都是4.??

7.2是指:宽度占7个,精确到小数点后两位(输出数据占7列,其中小数占2列)

1.左边界:只需要考虑相邻右元素是否存在坑

2.右边界:只需要考虑相邻左元素是否存在坑

3.中间:考虑相邻两边元素是否存在坑

我要回帖

更多关于 含有某字段则返回指定值 的文章

 

随机推荐