C语言复习—宏与函数、sizeof与strlen区别总结

#define定义的宏和函数的比较

  • 程序编译过程

    预编译阶段(*.i) —>编译(*.s)—>汇编(*.o)—>链接
    预处理在预编译阶段,做一些代码文本的替换工作,主要处理#开头的预编译指令。
    C语言提供的预处理功能有:
    1)宏定义
    2)文件包含
    3)条件编译

  • 宏定义的函数和用户自定义的函数的区别及优缺点?

    宏的优势

    1. 宏函数在预处理阶段展开,只占编译时间,函数调用则会占用运行时间(分配单元,保存现场,值传递,返回),每次执行都要载入,所以执行相对于宏来说较慢;
    2. 在函数调用时,需要先求出表达式的值,然后代入参数,而宏只是简单地字符替换;
    3. 函数调用是在运行时处理的,会分配临时的内存单元;而宏展开则是在编译期间完成的,不分配内存单元,不进行值传递,无返回值。
    4. 函数调用中的实参和形参都要定义类型,类型不匹配则无法编译,或者进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型。宏定义时,字符串可以是任何类型的数据。

    宏的缺点

    1. 每次使用宏的时候,就要把宏定义的代码放入程序中,如果代码过长就会降低代码的执行效率;
    2. 宏无法调试;
    3. 宏与类型无关,说明它不够严谨;
    4. 宏会出现运算符优先级的问题,程序容易出错
    5. 如果宏参数带有副作用,可能会造成不可预知的错误。

    内联函数

    • 内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的;
    • 内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。可以像调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题;
    • 内联函数也有一定的局限性,就是内联函数的执行代码不能过多,如果内联函数的函数体过大,编译器一般会放弃内联的方式,采用调用普通函数。

    其它
    一般来说,用宏来表示简短的代码比较适合,在考虑效率的时候可以考虑使用宏或者内联。
    注:定义宏的时候不要吝啬加括号,能加上就加上吧
    #define MAX(a, b) ((a)>(B)?(a):(b)

sizeof与strlen

sizeof

sizeof是运算符,在编译期间就计算好了,因为它在头文件中typedef为unsigned int。它的功能是:获取能保证现实建立最大对象的字节大小。由于是在编译期间计算的,所以sizeof不能返回动态开辟的空间的大小。如果sizeof遇上字符串数组,不要忘了后面还有\0的大小。

当有以下参数时,sizeof返回的值表示的含义为:

数组——编译时分配的数组空间的大小
指针——存储该指针的空间的大小(也就是存储指针的地址长度,长整型)
类型——该类型所占空间的大小
对象——该对象实际占用的空间大小
函数——函数返回类型的大小,不能是void

strlen

strlen是函数,在运行时才计算大小,它的参数是字符指针char*。当数组名作为参数传入时,实际上数组就退化为指针了。它的功能是:返回字符串的长度。实际上是这样工作的:从所给字符串的第一个地址开始遍历,遇到\0结束,返回长度不包括\0

举例

const char *p1 =”Hello World”;
输出结果:sizeof(p1):4 strlen(p1):11

char p2[] =”Hello World”;
输出结果:sizeof(p2):12 strlen(p2):11

char p3[10] =”Hello”;
输出结果:sizeof(p3):10 strlen(p3):5

sizeof返回定义p3数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据。strlen只关心存储的数据内容,不关心空间的大小和类型。

char * parr = new char[10];
输出结果:sizeof(parr):4 strlen(parr):x(随机值) sizeof(*parr):1

二者区别

  1. sizeof是运算符,strlen是函数
  2. sizeof可以用类型做参数,strlen必须要char*,还有必须以\0结尾
  3. 数组作为sizeof的参数不退化,传递给strlen就退化为指针了
  4. sizeof求的是占用内存大小,strlen求的是字符串长度
  5. sizeof是在编译阶段就计算完成了,strlen要在运行时才能计算
  6. sizeof后面如果是类型必须加括号,若果是变量名就不需要,毕竟它只是个操作符

形参与实参

实参可以是常量,变量或表达式。
实参与形参的类型应相同或赋值兼容。
在调用函数过程中发生的实参与形参间的数据传递,常称为“虚实结合
1. 实参和形参必须保持类型上,数量上,顺序上,都要一致
2. 实参必须有明确的值才能传给形参
3. 函数调用中数据传送是单向的,由实参传向形参,形参只在函数内部有效
4. 形参只有在调用的时候才分配内存单元,函数调用完成之后立刻释放,实参的内容不会被改变。
5. 实参与形参是从右向左结合;

猜你喜欢

转载自blog.csdn.net/qq_40840459/article/details/81234718