跳转至

语言基础

静态全局变量,全局变量,局部变量特点

作用域有6种:全局,局部,类,文件,语句,命名空间

  • 作用域不同:
    • 全局变量:全局作用域
    • 静态全局变量:全局作用域+文件作用域
    • 局部变量:局部作用域
    • 静态局部变量:局部作用域
  • 所在空间不同:
    • 局部变量:栈
    • 静态变量:静态存储区
  • 生命周期不同:
    • 局部变量:出作用域即被回收
    • 全局,静态全局,静态变量:程序结束才被回收

野指针概念,产生原因以及如何避免

  • 概念:指向位置不可知的指针
  • 产生原因:释放指针后没有及时置空,依然指向该内存,其他应用程序访问可能造成非法访问
  • 避免方法:
    • 初始化置空
    • 释放完置空
    • 申请内存判空

C语言和C++区别

  • C是C++子集,C++可以很好兼容C语言
  • C面向过程,C++面向对象
  • C++安全性高,C语言存在安全隐患,如内存泄漏等
  • C++可复用性高,引入模板,有标准模板看STL

struct和class区别

  • struct描述一个数据结构集合,class是对对象的封装
  • struct默认权限publicclass默认权限private
  • class可以定义模板参数,struct不行

include种<>与""区别

  • <>:系统文件 "":自定义文件
  • 查找路径不同:""更广
    • <>:系统类库
    • “”:项目当前目录->系统类库

C和C++结构体区别

  • C权限只能为public,C++可以为publicprivateprotected
  • C种不允许有函数存在
  • C不允许继承
  • C使用结构体需要取别名或写上struct

导入C函数的关键字,C与C++编译时的不同

  • 关键字:externextern "C"指示编译器以C语言进行编译,而不是C++
  • 不同:C++支持重载,编译函数时会带上函数的参数类型,而C语言不支持,编译时只带函数名

C++从代码到二进制可执行文件过程

  • 四个过程:预编译 编译 汇编 链接

数组与指针的区别

  • 概念
    • 数组是用于存储多个相同类型数据的集合,数组名是首元素的地址
    • 指针相当于一个变量,存放的是其他变量在内存中的地址,指针名指向了首地址
  • 区别
    • 赋值
      • 同类型指针可以相互赋值
      • 数组只能一个一个赋值
    • 存储方式
      • 数组在内存中连续存放,存储空间不是栈就是静态区
      • 指针的存储空间不能确定
    • sizeof求法
      • 数组的内存大小:\(sizeof(数组名)\times sizeof(数据类型)\)
      • 32位机器是4,64位机器是8

函数指针

  • 定义:函数指针指向一个函数的指针
  • 定义形式
1
2
3
int func(int a);
int (*f)(int a);
f = &func;
  • 使用场景:回调,在别人的库里调用自己的函数

静态变量

  • 初始化:全局和静态变量,在代码执行前初始化,即编译初始化
  • 作用域:
    • 静态全局变量:全局作用域+文件作用域,其他文件无法使用
    • 静态局部变量:局部作用域
    • 类静态成员变量:类作用域
  • 所在空间:静态存储区
    • 生命周期:静态全局变量和静态局部变量在静态存储区,程序结束才回收,类静态成员变量在静态存储区,超出类作用域后即回收

nullptr能否调用成员函数

原因:编译时对象即绑定函数地址,和指针是否为空没有关系

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
//给出实例
class animal{
public:
    void sleep(){ cout << "animal sleep" << endl; }
    void breathe(){ cout << "animal breathe haha" << endl; }
};
class fish :public animal{
public:
    void breathe(){ cout << "fish bubble" << endl; }
};
int main(){
    animal *pAn=nullptr;
    pAn->breathe();   // 输出:animal breathe haha
    fish *pFish = nullptr;
    pFish->breathe(); // 输出:fish bubble
    return 0;
}  

宏函数和内联函数区别

  • 宏函数不是函数,只是用宏替换代替了函数调用,没有函数压栈退栈的过程,内联函数是函数,只是结构比较简单
  • 宏函数在预编译阶段把所有宏名用宏体替换,是简单的字符串替换,而内联函数是在编译的时候对所有调用内陆函数的地方进行代码展开,省去函数调用的开销
  • 宏函数无类型检查,直接替换,内联函数会进行类型检查

Note

函数的参数值和局部变量存放在栈中


i++和++i的区别

  • 赋值顺序
    • i++先赋值后加
    • ++i先加后赋值
  • 效率
    • 后置++比前置++执行慢
  • 能否作为左值
    • ++i能作为左值
    • i++不行

new和malloc的区别

  • new是操作符,malloc是函数
  • new有构造和析构函数,malloc
  • malloc需要指定申请内存大小,返回指针需要强制类型转换
  • new可以被重载,malloc不行
  • new更安全
  • new发送错误抛出异常,malloc返回null

define和const的区别

  • const用于定义常量,define用于定义宏,而宏也可用于定义常量
  • 定义常量时,区别如下:
    • const生效于编译阶段,define生效于预编译阶段
    • const定义的常量存储在内存中,需要额外内存空间,define运行时是直接的操作数,不存放在内存中
    • const定义常量带类型,不带会报错,define不带类型

指针函数与函数指针区别

  • 定义:
    • 指针函数是函数,返回值为指针
    • 函数指针是指针,指向一个函数
  • 写法:
1
2
指针函数int* cal(int a);
函数指针int (*fun)(int a);
  • 用法:
1
2
3
4
指针函数:int *a = cal(0);
函数指针:
fun = cal; 
int a = (*fun)(0);  

指针使用时的注意点

  • 防止野指针3点
    • 初始化置空
    • 申请内存完判空
    • 释放内存置空
  • 越界
    • 注意下标+-1,防止指针下标越界
  • 申请内存与释放内存相配对,防止内存泄漏

内联函数与函数区别

  • 定义时多了关键字inline
  • 内联函数避免函数调用的开销
  • 内联函数有限制,例如代码量较短,非递归函数等,普通函数无限制
  • 普通函数需要寻址,内联函数不需要

C++传值方式

  • 值传递:形参发生变化,实参不发生变化(用于对象时,这个对象会拷贝一个副本)
  • 引用传递:形参在函数体发生变化,实参也发生变化
  • 指针传递:指针指向不发生改变情况下,形参在函数体发生变化,实参也发生变化

Note

​指针传递不如引用传递安全


constconst的区别

  • const*是常量指针
  • *cosnt是指针常量