1.运算符运算规则:
2.#include <head.h>与"head.h"的区别
<head.h> 表示这个头文件是一个工程或标准头文件,查找过程会首先检查预定义的目录,我们可以通过设置搜索路径环境变量或命令行选项来修改这些目录
"head.h" 表明该文件是用户提供的头文件,查找该文件时将从当前文件目录(或者文件名指定的其他目录)中寻找文件,然后在标准位置寻找文件
3.#与##在#define中的作用
#的作用是将后面的参数转换为字符串
##是将前后的参数进行字符串连接
4.#define、const 的特点及区别
#define只是用来做文本替换的,生命周期止于编译器,存在于程序的代码段,在实际程序中它只是一个常数、一个命令中的参数,并没有实际的存在
const常量存在于程序的数据段,并在堆栈分配了空间,是一个run-time的概念,在程序中确确实实的存在着并可以被调用、传递,const常量有数据类型,而宏常量没有数据类型,编译器可以对const进行类型安全检查。
5.memcpy 和 strcpy 的区别
都是c的标准库函数,strcpy 是专门为字符串定义的,而memcpy不是为字符串定义的,是内存块拷贝函数,可以拷贝内存中的任何内容
6.递归存在的风险,替代
在递归调用的过程中,每一次递归调用都会保存现场,把当前的上下文压入函数栈,随着递归层数的深入,压入函数栈的内容越来越多,直到函数栈的空间用尽,而递归程序仍然没有满足返回的条件,继续向更深一层调用,就会产生栈溢出
所以:使用递归解决问题时要考虑到栈溢出的问题,如果确实有可能发生,可以考虑使用循环代替递归
7.栈空间和堆空间的区别
- 栈空间用于存储函数参数和局部变量,所需空间由系统自动分配,回收也由系统管理,无须人工干预,堆空间用于存储动态分配的内存块,分配和释放空间均由程序员控制,有可能产生内存泄漏
- 栈空间作为一个严格后进先出的数据结构,可用空间永远都是一块连续的区域,堆空间在不断分配和释放空间的过程中,可用空间链表频繁更新,造成可用空间逐渐碎片化,每块可用的空间很小
- 栈空间的默认大小只有几M的空间,生长方式是向下的,也就是向着内存减小的方向消耗空间,堆空间的理论大小是几G,生长方式是向上的,也就是向着内存地址增大的方向消耗空间
- 栈空间有计算机底层的支持,压栈和出栈都有专门的指令,效率较高,堆空间通过函数动态获取空间,涉及可用空间的扫描和调整以及相邻可用空间的合并等操作,效率相对较低
8.程序中的四大存储区
全局区(静态区):全局变量和静态变量存储是放在一起的,初始化的全局变量和静态变量放在一块区域,未初始化的静态变量和未初始化的动态变量在相邻区域,程序结束系统释放。
常量区:存放常量字符串
栈:一般由编译器操作,会存放一些局部变量等。
堆:一般有程序员管理,比如malloc申请内存,一般的对象都在堆区。
9.static 的作用
- 修饰局部变量时,延长局部变量生命周期,只会被初始化一次
-
修饰全局变量和函数都表示隐藏(限制了作用域),表示只能在本文件内使用,不允许被外部变量调用。
10.new/delete 与 malloc/free 的区别
- new/delete 是运算符,使用时不需要加头文件;malloc/free 是库函数,使用时需要加头文件<stdlib.h>,系统开销大
- malloc 的返回值是void*型指针,需要强转才能使用;new 数据类型的返回值是特定的数据类型指针,不需要强转
- new 申请内存的时候已经确定了内存中存放的数据类型,new 会做类型检查及指针的数据类型要和 new 后面的数据类型一致
- malloc 申请内存大小需要手动计算; new 只需要确定元素个数和类型
- free 的入参是内存的首地址;delete 内存要分情况:delete p;delete[]p
- new 一个对象时会自动调用该对象的构造函数,delete 一个对象会自动调用该对象的析构函数;malloc 没有这个功能
11.sizeof 和strlen 的区别
- sizeof 是操作符,strlen 是函数
- sizeof 操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型,该类型保证能容纳实现所建立的最大对象的字节大小
- sizeof 可以用类型做参数,strlen 只能用char*做参数,且必须是以'\0'结尾的
- 数组做sizeof的参数不退化,传递给strlen就退化为指针了
- 大部分编译程序在编译的时候sizeof就被计算过了,这就是sizeof(x)可以用来定义数组维数的原因,strlen的结果要在运行的时候才能计算出来,它用来计算字符串的长度,不是类型所占内存的大小
- sizeof后如果是类型,必须加括弧,如果是变量名,可以不加括弧,这是因为sizeof是个操作符,而不是个函数
- 在计算字符串数组的长度上有区别
- sizeof 是用来测字节数的,包含’\0’,而strlen 是用来求长度的,不包含’\0’;
- sizeof 是运算符,strlen 是函数。
12.sizeof 的错误使用
1.位域不可以 2.函数名不可以 3.返回值为空不可以
13.sizeof 的用途
- 计算常量所占字节数
- 计算数据类型所占字节数
- 计算变量所占字节数
14.pragma pack 指令的作用
15.指针和数组
16.复杂指针的声明
用变量a给出下面的定义:
- 一个整型数
- 一个指向整型数的指针
- 一个指向指针的指针,它指向的指针是指向一个整型数的
- 一个有10个整型数的数组
- 一个有10个指针的数组,该指针是指向一个整型数的
- 一个指向有10个整型数数组的指针
- 一个指向函数的指针,该函数有一个整型参数并返回一个整型数
- 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型
- 答案:
- int a;
- int *a;
- int **a;
- int a[10];
- int *a[10];
- int (*a)[10];
- int(*a)(int);
- (*a[10])(int);
17.用指针赋值
18.指针加减法操作
19.指针比较
20.指针数组和数组指针
21.数组指针与二维数组
22.指针函数和函数指针区别
指针函数是返回值为指针的函数
函数指针是指向函数的指针
23.指针常量和常量指针区别
指针常量就是指针的常量,它是不可改变地址的指针,但是可以对它所指向的内容进行修改
常量指针就是指向常量的指针,它所指向的地址的内容是不可修改的
24.const关键字在指针声明时的作用
const char *p; //常量指针 p指向可变
char *const p; //指针常量 *p指向可变
18.指针常量和字符串
19.指针数组与指向指针的指针
20.指向指针的指针与二维数组的区别
21.指针作为参数的常见错误
22.野指针及危害
野指针:不是NULL指针,而是指向“垃圾”内存的指针,其主要成因是因为:指针变量没有被初始化,或指针p被free或者delete之后,没有被置为NULL
危害:会导致程序运行崩溃
23.数组地址与数组首元素地址的区别
24.预处理