C语言如何获取逻辑或运算的第一个非空值而非布尔结果?
问题根源
C 语言的||运算符的返回值固定为整型布尔值:操作数任意一个为真返回1,全假返回0,不会返回操作数本身的值,所以你直接将||的运算结果作为指针返回,自然会触发类型不匹配的编译警告。
解决方案
方案1:三元运算符(适配少量判断场景)
你可以用三元表达式模拟JS||的行为,逻辑为a ? a : b,具备短路特性:只要a非空就直接返回a,不会执行后续的b。
如果调用的函数无副作用(多次执行不会产生额外影响),可以直接改写你的choice函数:
char* choice() { return foo() ? foo() : bee(); }
如果函数有副作用,不想重复执行,可以加临时变量存储结果:
char* choice() { char* res = foo(); return res ? res : bee(); }
方案2:宏封装(适配多判断场景,无需写大量if else)
如果需要处理foo() || bar() || tar() || mar() || far()这类多判断场景,可以封装可变参数的宏来简化调用,以下是基于GCC语句扩展的实现,不会重复求值操作数:
// 基础两个操作数的指针OR宏 #define OR_PTR(a, b) ({ \ __typeof__(a) _a = (a); \ _a ? _a : (b); \ }) // 扩展支持多操作数 #define OR_PTR3(a, b, c) OR_PTR(OR_PTR(a, b), c) #define OR_PTR4(a, b, c, d) OR_PTR(OR_PTR3(a, b, c), d) #define OR_PTR5(a, b, c, d, e) OR_PTR(OR_PTR4(a, b, c, d), e)
使用时直接替换原来的||写法即可:
char* choice() { // 两个参数的场景 return OR_PTR(foo(), bee()); // 五个参数的场景示例:return OR_PTR5(foo(), bar(), tar(), mar(), far()); }
方案3:标准C兼容实现(无编译器扩展依赖)
如果需要兼容所有C标准,可以把同返回类型的函数放到数组中循环判断,实现同样的效果:
// 封装通用的取第一个非空返回值的函数,仅针对返回char*的无参函数 char* get_first_non_null(int func_count, char* (*func_arr[])()) { for (int i = 0; i < func_count; i++) { char* res = func_arr[i](); if (res != NULL) return res; } return NULL; }
调用示例:
char* choice() { char* (*funcs[])() = {foo, bee, bar, tar, mar}; return get_first_non_null(5, funcs); }
修改后的可运行测试代码
#include <stdio.h> #include <stdlib.h> #define OR_PTR(a, b) ({ \ __typeof__(a) _a = (a); \ _a ? _a : (b); \ }) char* foo() { return NULL; } char* bee() { return "I don't like you, short guy!"; } char* choice() { return OR_PTR(foo(), bee()); } int main() { char* result = choice(); if(result == NULL) { printf("GOt a null again"); return 1; } printf("Horray! Succsex! %s", result); return 0; }
内容的提问来源于stack exchange,提问作者user15307601
相关产品推荐
相关产品推荐

