2023届C/C++软件开发工程师校招面试常问知识点复盘Part 2

10、函数指针、指针函数、回调函数
10.1 函数指针

指向函数的指针变量,该变量指向了函数在内存中的地址(代码段)

定义方式返回值类型 (* 函数指针名) (函数参数)

int (* pfunc) (int x, int y);  // 定义一个函数指针
int (* pfunc) (int, int y); // 注意形参可以忽略
int add(int x, int y)
{
    
    
    return x + y;
}

// main() 函数内
int (*pfunc)(int x, int y);
pfunc = add;
// int (*pfunc)(int x, int y) = add; // 替代7、8两行直接进行初始化
printf("%d\n", pfunc(1, 2)); 

函数指针的用途

调用函数,利用指针调用函数,把函数指针视作函数名直接进行函数调用;如上文的pfunc的案例~

注意:在使用函数指针调用函数时,对函数指针解引用和不解引用都是可以的,我觉得不加*更简洁

做函数的参数,形成回调函数

10.2 指针函数

指针函数是一个返回指针的函数;与普通函数的区别就是返回值的类型不同

定义方式

int* func(int x, int y);
  • 函数指针指针函数的区别显而易见:

    1. 函数指针本质上是一个指针,其指向一个函数;指针函数本质上是一个函数,其返回值是一个指针

    2. 写法上:

      函数指针:(带有*括号)
          int (* pfunc) (int x, int y);
      指针函数:
          int* func (int x, int y);
      

10.3 回调函数

回调函数

  • 把一段可以执行的代码像参数传递那样传递给其他的代码,然后这段代码在未来的某一个时刻调用执行,也即回调
  • 如果代码被立即执行称为同步回调,如果延迟执行称为异步回调
  • 回调函数就是一个通过函数指针来调用的函数,也就是上文中所指的那个被传递的函数。如果把函数的指针作为参数传递给另一个函数,当这个指针用于调用其指向的函数时就是所谓的回调函数

抽象一点来讲:(是一种晚绑定机制,更加灵活)

回调函数并不是由函数的实现方直接调用,而是在特定的事件发生后被另外的一方调用,用于对该事件或条件进行响应(例如MFC框架调用按钮控件的响应函数跟这个很类似)。

有点类似C++设计模式中的模板方法———Template Method的作用

11、TCP和UDP区别?
  • UDP是无连接的,面向应用报文的,提供不可靠传输服务

  • 无连接:指不需要事先建立连接就可以直接传输数据

  • 面向应用报文:指UDP不会对应用层发来的报文合并和拆分

  • 不可靠传输服务:指数据报在传输过程中发生误码、丢失等后什么也不做,丢了就丢了

  • 可以进行单播、多播、组播;主要用于IP电话、视频会议等实时应用,还有DNS服务


TCP是面向连接的,面向字节流的,提供可靠传输服务

  • 面向连接:指的是在传输数据之前需要先通过3次握手建立连接,传输数据后需要通过4次挥手释放连接

  • 面向字节流的:指的是仅将应用层下发的数据看作字节流,TCP根据其最大报文段长度对字节流进行合并或分割

  • 提供可靠传输:指的是在协议和逻辑上,不会发生丢包、误码、乱序、重复等错误现象,这都要依靠TCP的流量控制拥塞控制等功能

  • 只能进行单播;主要用于要求可靠传输的应用,如文件传输

12、TCP中的超时重传是在哪一层实现?

运输层

13、怎么解决粘包问题?

方式1:消息定长,每次发送的数据量固定,这样接收方就可以根据这个固定值区分不同的包

方式2:为每一个包加一个2~4字节头部,其中包含了该包的大小,接收方先读取这个长度,然后再根据长度确定包的边界

14、帧头是怎么写的?怎么实现的区分帧头每一帧数据?

在这里插入图片描述

以太网帧:帧头部(6[目标mac] + 6[源mac] + 2[协议类型]+ IP包 + 帧[FCS校验位]的尾部

IP包: IP头部(20字节) + 数据部分(TCP报文段)(注意:MTU由物理层的协议决定,例如以太网帧的MTU最大为1500Bytes

TCP报文段:TCP头部(20字节) + 数据部分(数据部分一般是http消息报文

15、写一个socket服务端需要那些步骤?

创建socketbindlistenacceptwrite/readclose

16、用过C和C++的混编吗?extern "C"的作用和存在意义?

简单使用过:

  • 1、首先毫无疑问extern "C"是用于C++语言和C语言混合编程相互调用的,这个"C"更本质的讲也包括所有的类C语言和与C语言编译链接方式相同的语言

  • 2、在C++源文件或相关的头文件中写了extern "C",就表明接下来的代码要按照C语言的规则进行编译和链接,而不是按照C++的方式;不过这个仅仅改变编译和链接规则,不会改变代码语义,该遵守的C++代码语法还是要遵守的。

  • 3、如果在C++中调用C语言的函数,就需要在要调用的函数声明前头文件前加上extern "C"

  • 4、如果要在C语言中调用C++函数,那么C++在定义函数时,需要加上extern "C"表明其编译链接方式,这样才可以被C语言调用;而C语言进行调用时,需要用extern关键字先进行声明,表明是外来的函数


extern关键字:

extern也可以单独使用,在单独使用时表示表明它声明变量或函数是一个外部变量或函数,已经在其他文件或模块中定义过了;同样也可以扩展全局变量的作用域

extern只用于声明,不是用于定义的。

17、int型数组:int arr[10];那么sizeof(arr)是多少?用一个指针指向这个数组,sizeof这个指针大小是多少?

40和4

18、new和malloc的区别?
  • mallocfree标准库函数,支持覆盖;C的
  • new和delete是运算符,不重载;Cpp的
  • malloc仅仅分配内存空间free仅仅回收空间,不具备调用构造函数和析构函数功能,用malloc分配空间存储类的对象存在风险
  • new和delete除了分配、回收功能外,还会调用构造函数和析构函数
  • malloc和free返回的是void类型指针(必须进行类型转换),new和delete返回的是具体类型指针

new运算符—>operator new标准库函数—>先分配足够的空间—>调用构造函数创建对象

delete—>对指针指向的对象,调用其析构函数—>调用operator delete库函数—>释放内存空间

19、做项目的过程中有没有遇到要调用一个库的情况?怎么用的?makefile中要写什么才能调用到这个库?

-l 指定这个库的名称;例如:-lpthread

1、make是一个linux系统中的一个工具也是一个命令,是一个解释 makefile 中指令的命令工具

2、makefile 定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作;

因为 makefile 就像一个 Shell 脚本一样,其中也可以执行操作系统的命令。

20、写过makefile吗?它的作用?

简单写过:

1、makefile文件主要是为了给make工具解释,然后用于指导程序编译构建的

2、它内部由一条条的规则组成,每一个规则通常情况下都由目标依赖命令

3、他的执行逻辑是默认是执行第一条规则,如果第一条规则执行完,也就结束了

4、也可以直接make + 目标,这样make运行时就会找到目标所代表的那条规则进行执行,例如我们常用的make clean

猜你喜欢

转载自blog.csdn.net/qq_40459977/article/details/127516480
今日推荐