这个带有指针的函数似乎根本不会执行
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 );
事实上,p
和 q
指针是多余的。你也可以像这样调用函数
swap( &a, &b );
【讨论】:
以上是关于这个带有指针的函数似乎根本不会执行的主要内容,如果未能解决你的问题,请参考以下文章