C语言 三元运算符中的指针

ehxuflar  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(162)

当我在三元运算符中使用指针时,如果条件为真,它将执行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;
}
eqoofvh9

eqoofvh91#

您的代码中有几个问题会导致undefined behaviour第一个问题是你不恰当地使用了指针算法。像递增、递减和比较这样的操作只有在指向数组元素的指针上才真正有用。在你的例子中,ab都不是数组(尽管从编译器的Angular 来看,它们可以被视为单元素数组),因此编译器没有义务为这些变量遵循任何特定的 * 相对 * 内存安排:它们 * 可以 * 在存储器中相邻,或者被任意数目的字节分隔;并且即使它们 * 是 * 相邻的,它们也可以是“任意一种”(即,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标准没有指定>的哪个操作数先被求值(即>操作符是 not a sequence point),因此,使用中间变量扩展编译器可能解释它的方式,我们可以得到:

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就保持不变:

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

相关问题