C函数调用产生的结果与C++函数调用不同
C function call produces different result than C++ function call
我有这个C代码:
#include <stdio.h>
#include <windows.h>
int main() {
int i;
while(1) {
for (i = 8; i <= 190; i++) {
if (GetAsyncKeyState(i) == -32767) // That number doesnt actually work, only works with -32768 (which checks to see if the key is pressed down)
printf("%cn",i); // When using -32768, it prints the key if it is held down about 20 times
}
}
return 0;
}
所以-32767在那个C代码中不起作用,但我有一个C++代码:
#include <iostream>
using namespace std;
#include <windows.h>
int main() {
char i;
while (1) {
for(i = 8; i <= 190; i++) {
if (GetAsyncKeyState(i) == -32767) // works as intended, prints the pressed key letter (doesnt have to be held down)
cout << i << endl;
}
}
return 0;
}
与-32767配合使用。这是非常令人困惑的,因为这两个都是在同一台计算机上用相同的命令运行的:clang++ test.c
C输出-32768(按A):
A
A
A
A
A
A
A
A
A
A
A
用-32767:输出C++代码
A
B
C
D
E
F
G
H
具有-32767的C代码输出:(无)
根据GetAsyncKeyState:的文档
如果函数成功,则返回值指定自上次调用GetAsyncKeyState以来是否按下了该键,以及该键当前是向上还是向下。如果设置了最高有效位,则键向下;如果设置了最低有效位,那么键在上次调用GetAsyncKeyState之后被按下但是,您不应该依赖这最后一个行为;有关详细信息,请参阅备注。
这说明将-32768
与-32767
区别对待是不可靠的。它也没有说明中间的所有比特,但您的代码假设它们是1
比特,而没有理由。
为了可靠,您的代码应该只对返回值进行以下测试:
>= 0
-密钥当前已打开,或信息不可用< 0
-按键当前关闭
您的代码依赖于实现定义的行为。看起来您的C编译器使用的是无符号的char
s,而C++编译器使用的却是有符号的。这就是为什么C中的嵌套循环一直到190,而C++中的同一个循环在达到128时循环到零。
您可以通过在两个实现中将i
的类型设置为unsigned char
来解决此问题。您也可以将i
设为int
,并在GetAsyncKeyState
函数的调用中为char
添加强制转换。
请参阅本主题:http://www.cplusplus.com/forum/general/141404/-32767在二进制中实际上是1000 0000 0000 0001,当你比较GetAsyncKeyState(i)的返回值时,你基本上是在问是否只有左位和右位打开,但正如上面的链接中所说,位1-14可能并不总是零。一个更恰当的表达是这样的:
if (GetAsyncKeyState(i) & -32767)
或者可以使用十六进制文字:
if (GetAsyncKeyState(i) & 0x8001)
实际上,C实现不起作用的原因是因为我在mingw32终端中手动执行./a
,由于某种原因,直到按下了很多键后,它才打印任何内容,所以我只是双击执行a.exe
,它就起了作用,这是一种非常奇怪的体验:/
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销