MST

星途 面试题库

面试题:复杂C语言宏函数的设计与副作用预防

设计一个C语言宏函数,该宏函数实现对一个数组中所有元素求和操作,且要考虑到宏函数调用过程中可能产生的各种副作用并加以避免。数组元素类型为`int`,宏函数需要接受数组指针和数组长度作为参数。同时,解释在实现过程中采取避免副作用措施的原理。
33.1万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#include <stdio.h>

#define ARRAY_SUM(arr, len) \
({ \
    int sum = 0; \
    const int *p = (arr); \
    int l = (len); \
    for (int i = 0; i < l; ++i) { \
        sum += p[i]; \
    } \
    sum; \
})

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int len = sizeof(arr) / sizeof(arr[0]);
    int result = ARRAY_SUM(arr, len);
    printf("Sum of array elements: %d\n", result);
    return 0;
}

避免副作用措施的原理

  1. 使用临时变量:在宏中使用了临时变量 sumpl 来存储中间结果和输入参数。这样做是为了避免对传入的数组指针 arr 和数组长度 len 直接进行操作。如果不使用临时变量,宏在多次使用 arrlen 时可能会导致副作用,比如 len 被多次求值(如果 len 是一个表达式)。例如,如果 len 是一个包含自增操作的表达式,直接使用 len 会导致 len 的值在宏内部多次变化,结果不符合预期。
  2. 使用 const 修饰指针:将数组指针 p 声明为 const int *,这样可以防止宏内部意外修改传入的数组内容。如果没有 const 修饰,宏函数内部可能不小心对数组进行了修改,这在一些场景下会导致严重的副作用。
  3. 使用 ({ }) 复合语句表达式:在C99标准中,({ }) 复合语句表达式允许在其中定义局部变量,并返回最后一个表达式的值。这种方式可以将宏函数的逻辑封装起来,避免与外部代码产生命名冲突等副作用。如果不使用 ({ }),宏内部定义的变量(如 sumpl)可能会与调用宏的代码中的变量重名,导致意外的结果。