这个带有指针的函数似乎根本不会执行
This function with pointers seemingly won't execute at all
我正在尝试制作一个程序,该程序使用按位运算符交换函数中的 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);
}
编译器应该为这一行发出错误或至少一条警告消息
void swap(p, q);
因为不正确。
它是一个带有标识符列表的函数声明,但在不是同时定义它的函数声明中,标识符列表应为空。
相反,您需要调用函数 swap
swap( p, q );
实际上指针p
和q
是多余的。您也可以像
这样调用函数
swap( &a, &b );
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
可读性更强,效率更高。
编辑:实际上我刚刚又玩了一轮,异或版本的低效率主要来自指针可能混叠的假设。将函数更新为 void xor_swap(int* restrict a, int* restrict b)
使其与 tmp_swap
一样快(但可读性仍然较差)。
我正在尝试制作一个程序,该程序使用按位运算符交换函数中的 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);
}
编译器应该为这一行发出错误或至少一条警告消息
void swap(p, q);
因为不正确。
它是一个带有标识符列表的函数声明,但在不是同时定义它的函数声明中,标识符列表应为空。
相反,您需要调用函数 swap
swap( p, q );
实际上指针p
和q
是多余的。您也可以像
swap( &a, &b );
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
可读性更强,效率更高。
编辑:实际上我刚刚又玩了一轮,异或版本的低效率主要来自指针可能混叠的假设。将函数更新为 void xor_swap(int* restrict a, int* restrict b)
使其与 tmp_swap
一样快(但可读性仍然较差)。