当我在三元操作符中使用指针时,如果条件为真,则执行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)。首先是指针算术使用不当。像自增、自减和比较这样的操作只对指向数组元素的指针有用。在您的情况下,a
和b
都不是数组(尽管,从编译器的角度来看,它们可以被视为单元素数组),因此编译器没有义务遵循这些变量的任何特定相对内存安排:它们可以在内存中相邻,或由任意数量的字节分隔;而且,即使它们是相邻的,它们也可以是'任意方向'(即a
或b
都可以在较低的地址中)。
a
和b
令牌为该数组的元素别名:
// 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);