C语言 三元操作符指针



当我在三元操作符中使用指针时,如果条件为真,则执行exp3

#include <stdio.h>
int main(){
int a,b;
printf("Enter first number:");
scanf("%d",&a);
printf("Enter second number:");
scanf("%d",&b);
printf("Address of a:%u n",&a);
printf("Address of b:%u n",&b);
int *ptr=&b;
// when i use pointer in ternary operator if condition is true it execute exp3
// problem in this line 
(*ptr++) > (*ptr) ? printf("n %d is the maximum number",b):printf("n %d is the maximum number",a);
(a>b) ? printf("n %d",a) : printf("n %d",b);
return 0;
}

您的代码中有几个问题会导致未定义行为(UB)。首先是指针算术使用不当。像自增、自减和比较这样的操作只对指向数组元素的指针有用。在您的情况下,ab都不是数组(尽管,从编译器的角度来看,它们可以被视为单元素数组),因此编译器没有义务遵循这些变量的任何特定相对内存安排:它们可以在内存中相邻,或由任意数量的字节分隔;而且,即使它们是相邻的,它们也可以是'任意方向'(即ab都可以在较低的地址中)。

我们可以在代码中创建一个"快速解决方案",通过声明一个实际数组,然后使ab令牌为该数组的元素别名:
//  int a, b;
int data[2];
#define a (data[0])
#define b (data[1])

另一个导致UB的原因是在显示指针时使用了错误的printf格式说明符;指针应该使用%p说明符打印,即使这样,当作为参数传递给printf时,也应该真正转换为void*:

printf("Address of a:%p n", (void*)&a);
printf("Address of b:%p n", (void*)&b);

但是第三个——也许也是最重要的——UB的来源出现在"条件"中。条件('三元')运算符的表达式:(*ptr++) > (*ptr)比较。

对于这个表达式,C标准没有指定>的哪个操作数首先求值(即>运算符是而不是一个序列点)。因此,扩展编译器如何解释这个,使用中间变量,我们可以得到:

T1 = (*ptr++);   // T1 will get the value of "a", then "ptr" is incremented
T2 = (*ptr);     // T2 will get the value of "b"
if (T1 > T2) ... // This will now be equivalent to the "a > b" comparison

或者,编译器同样有权这样做:

T1 = (*ptr);     // T1 will get the value of "a"
T2 = (*ptr++);   // T2 will ALSO get the value of "a" and THEN 'ptr' is incremented
if (T1 > T2) ... // This will now be equivalent to the "a > a" comparison - which is wrong

我们可以通过显式地使用像上面那样的中间变量来解决这个UB:

int T1 = *ptr++;
int T2 = *ptr;
T1 > T2 ? printf("n %d is the maximum number", b) : printf("n %d is the maximum number", a);
但请注意,即使这样,由于应用后增量的方式(即之后的),您的代码也会显示错误的答案。*ptr的值已经赋给T1).

如果必须在代码中使用指针,则避免后增量,只需使用简单的加法来获得b(或第二个元素)的地址,从而在使用ptr引用a(第一个元素)时保持不变:

*(ptr+1) > *ptr ? printf("n %d is the maximum number", b) : printf("n %d is the maximum number", a);

最新更新