这个带有指针的函数似乎根本不会执行

Posted

技术标签:

【中文标题】这个带有指针的函数似乎根本不会执行【英文标题】:This function with pointers seemingly won't execute at all 【发布时间】:2022-01-14 02:08:29 【问题描述】:

我正在尝试制作一个程序,用位运算符交换函数中的 2 个变量,但该函数不会做任何事情。我很确定我得到了正确的 XOR 交换的基本逻辑(我通过手动进行一些操作进行检查,并在 main 中检查),但由于某种原因,功能块不会做任何事情。另外我对 C 编程很陌生,所以请原谅我没有发现一些明显的愚蠢错误。

代码是:

#include <stdio.h>


void swap(int *a, int *b)

    printf("value of a=%d b=%d before swapping\n", *a, *b);
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
    printf("value of a=%d b=%d after swapping\n", *a, *b);



int main()

    int a, b, *p, *q;
    printf("Enter 2 numbers to be swapped: \n");
    scanf("%d %d", &a, &b);
    p = &a;
    q = &b;
    void swap(p, q);
    printf("\nfinal %d %d", a, b);

【问题讨论】:

您可以按照 Passerby 所说的进行修复,但您也可以借此机会提高您的调试技能: 第 1 步:使用 -Wall 编译代码时是否收到任何警告?如果是,它们是什么,你明白它们的意思吗?哦,欢迎来到 SO,并祝贺第一个问题写得很好! 一个体面的编译器应该是warning you 关于该代码。听取编译器发出的警告,并将它们视为必须修复的错误。 是的,我不明白编译器闪过的警告,有点忽略了它......谢天谢地,Lundin 专门指出了一个修复程序并修复了它!我想我会修改函数。 【参考方案1】:

gcc 即使没有-Wall 也会指出错误的确切位置。只需编译代码并查看它指向的位置:

warning: parameter names (without types) in function declaration
      |     void swap(p, q);
      |     ^~~~

^ 箭头表示“这里有错误”。只需在函数调用中删除void

此外,XOR 交换是那些“为了它而混淆”的东西之一。它的唯一目的似乎是摆姿势,因为临时变量交换通常会产生更高效的代码。在 x86 gcc -O3 上查看此基准测试:

void xor_swap(int *a, int *b)

    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;


void tmp_swap(int *a, int *b)

  int tmp = *a;
  *a = *b;
  *b = tmp;


xor_swap:
        mov     eax, DWORD PTR [rdi]
        xor     eax, DWORD PTR [rsi]
        mov     DWORD PTR [rdi], eax
        xor     eax, DWORD PTR [rsi]
        mov     DWORD PTR [rsi], eax
        xor     DWORD PTR [rdi], eax
        ret

tmp_swap:
        mov     eax, DWORD PTR [rdi]
        mov     edx, DWORD PTR [rsi]
        mov     DWORD PTR [rdi], edx
        mov     DWORD PTR [rsi], eax
        ret

tmp_swap 更具可读性和效率。


编辑:实际上我刚刚用这个多玩了一轮,XOR 版本的低效率主要来自指针可能别名的假设。将函数更新为 void xor_swap(int* restrict a, int* restrict b) 使其与 tmp_swap 一样快(但可读性仍然较差)。

【讨论】:

a = b 时,tmp_swap(a, b) 仍然有效。 xor_swap(a,b) 在功能上无法交换(将数据清零)。【参考方案2】:

编译器应该为此行发出错误或至少警告消息

void swap(p, q);

因为它不正确。

它是一个带有标识符列表的函数声明,但在不是同时定义其定义的函数声明中,标识符列表应为空。

你需要调用函数swap

swap( p, q );

事实上,pq 指针是多余的。你也可以像这样调用函数

swap( &a, &b );

【讨论】:

以上是关于这个带有指针的函数似乎根本不会执行的主要内容,如果未能解决你的问题,请参考以下文章

js中调用函数时加不加括号的问题

为啥带有 setTimeout 的函数不会导致堆栈溢出

函数指针与类成员函数指针

函数指针和指针函数用法和区别

提升 C++。将带有签名指针的成员函数指针传递给函数

带有指针参数的 C++ 函数