C语言三元运算符计算数组中间索引结果为0及变量初始化用法疑问
三元运算符写法错误排查与修正
错误根因
- 三元运算符是可返回值的表达式,语法结构为
条件 ? 表达式A : 表达式B,执行规则是条件成立就返回表达式A的计算结果,不成立就返回表达式B的计算结果,本身不适合直接用来在分支内执行零散的赋值操作。 - 原代码的实际执行逻辑为:当数组长度为偶数时,将
长度/2的值赋值给对应的中间索引变量;当数组长度为奇数时,仅在内存中计算出(长度/2)-1的数值,完全没有将这个计算结果赋值给中间索引变量。 - 测试用的两个数组长度均为5(奇数),程序全程走三元表达式的冒号分支,从未触发对
middle_index1、middle_index2的赋值流程。这两个变量是栈上未初始化的局部变量,读取其值属于未定义行为,本次运行环境恰好给这两个变量分配的初始值为0,才会出现中间索引恒为0的输出。
三元运算符的适用场景
三元运算符完全可以用于变量初始化、赋值场景,只需要把三目表达式整体的返回值赋值给目标变量即可,不需要在两个分支内单独写赋值逻辑。
正确写法示例:
middle_index1 = (array_s1 % 2 == 0) ? (array_s1 / 2) : (array_s1 / 2 - 1); middle_index2 = (array_s2 % 2 == 0) ? (array_s2 / 2) : (array_s2 / 2 - 1);
这种写法无论数组长度是奇数还是偶数,三目运算符都会根据判断返回对应计算值,再整体完成赋值,不存在分支漏赋值的问题。
修正后的完整可运行代码
#include <stdio.h> int middle(int array1[], int array2[], int array_s1, int array_s2) { int middle_index1, middle_index2; // 修正后的三元赋值逻辑 middle_index1 = (array_s1 % 2 == 0) ? (array_s1 / 2) : (array_s1 / 2) - 1; middle_index2 = (array_s2 % 2 == 0) ? (array_s2 / 2) : (array_s2 / 2) - 1; printf("Elements in the original arrays:\n"); for (int i = 0 ; i < array_s1 ; i ++) { printf("%i, ", array1[i]); } printf("\n"); for (int i = 0 ; i < array_s2 ; i ++) { printf("%i, ", array2[i]); } printf("\nMiddle indexes = %i , %i", middle_index1, middle_index2); int new_array[] = {array1[middle_index1], array2[middle_index2]}; int array_s3 = sizeof(new_array) / sizeof(new_array[0]); printf("\nElements in the new array:\n"); for (int i = 0 ; i < array_s3 ; i++) { printf("%i, ", new_array[i]); } // 补全原函数缺失的返回值,消除未定义行为 return 0; } int main(void) { int array1[] = {10, 20, -30, -40, 30}; int array2[] = {120, 20 , 30, 40, 30}; int array_s1 = sizeof(array1) / sizeof(array1[0]); int array_s2 = sizeof(array2) / sizeof(array2[0]); middle(array1, array2, array_s1, array_s2); }
修正后运行时,两个长度为5的奇数数组对应的中间索引为(5/2)-1 =1,取到的元素为数组索引1位置的值,不会再出现索引恒为0的异常。
内容的提问来源于stack exchange,提问作者TheHawk3r
相关产品推荐
相关产品推荐

