我注意到在C中,我的布尔变量以某种我不明白的方式改变了。
var notification = {
TableName: "Tablename",
KeyConditionExpression:"#userId =:userid and #datetime <=:datetime",
ScanIndexForward: false,
ExpressionAttributeNames: {
"#userId": "userId",
"#datetime":"datetime"
},
ExpressionAttributeValues: {
":userid" :userId,
":datetime" :datetime
}
};
docClient.query(notification, function(err, result) {
if (err) {
context.succeed({success: false, message : JSON.stringify(err, null, 2),method:"notification",type:type});
}else{
result = result.Items;
if (result.length>0) {
for(var i=0;i<result.length;i++){
result[k]['CafeDetail']=getDetail(result[k].CafeID,function (data) {
});
if (k ==(result.length -1)) {
context.succeed({success: true,data:result, message : "Notification list",method:"notification",type:type});
}
}
}
}
});
function getDetail(CafeID,callback) {
var param = {
TableName: "Tablename",
ProjectionExpression:"CafeName,Cafe_MainImage",
KeyConditionExpression:"CafeID =:cafeID",
ExpressionAttributeValues: {
":cafeID" :CafeID
}
};
docClient.query(param, function(err, CafeDetail) {
if (err) {
console.log (err)
callback(err);
} else {
callback(CafeDetail.Items);
console.log(CafeDetail.Items);
}
});
}
如果我为#include <stdio.h>
#include <stdbool.h>
int main(void) {
bool x, y;
printf("x: ");
scanf("%d", &x);
printf("x is %d\n", x);
printf("y: ");
scanf("%d", &y);
printf("x is %d\n", x);
printf("y is %d\n", y);
return 0;
}
输入1
的值,并为此示例中的x
(y
)输入任何值:
1
最后,x: 1
x is 1
y: 1
x is 0
y is 1
输出正确的原始值,但y
神奇地更改为x
!
当0
的输入为x
时,这不是问题,因为0
和x
的输出都是预期的原始值。
请解释发生了什么!
答案 0 :(得分:8)
您将布尔变量的地址传递给scanf()
,其中需要int*
类型的变量。这将调用未定义的行为,您可能会得到错误的结果甚至崩溃。
要解决此问题,请使用临时int
来存储布尔值的扫描(作为int),然后将其存储为布尔变量。
<强>演示强>
bool x, y;
int tmp;
printf("x: ");
scanf("%d", &tmp);
x = tmp;
另一方面,打印boolan变量是不同的故事,其中布尔值被引导到int而没有任何问题并正确打印。
答案 1 :(得分:7)
好的,这里有两点。
bool
的大小是实现定义的。bool
类型定义格式说明符。因此,当扫描值时,将bool
的地址作为%d
的参数传递为,请参阅注释作为提供的type与预期类型不同。
您可以使用中间整数,将值扫描到该值,并且(在验证或转换为true
和false
MACRO之后)将结果分配回bool
类型变量。
但是,对于打印,由于默认参数提升,bool
可以成为%d
参数的候选者而没有问题。
注意:
带有%d
的 *scanf()
期望参数为int *
,而提供bool*
会导致undefined behavior。
相关,引用章节§7.21.6.2,第10段
[....]除非
*
表示分配抑制,否则 转换结果放在下面第一个参数指向的对象中 尚未收到转换结果的format
参数。 如果是这个对象 没有合适的类型,或者无法表示转换结果 在对象中,行为未定义。
答案 2 :(得分:7)
bool
不是int
。使用%d
的{{1}}格式说明符读取它是未定义的行为。
每 7.21.6.2 int
函数,第13段of the C standard:
如果转换规范无效,则行为未定义。
请注意 7.21.6.1 fscanf
函数第9段规定:
如果转换规范无效,则行为为 未定义。如果任何参数不是正确的类型 相应的转换规范,行为是 未定义。
但是fprintf
的那个,而不是fprintf()
。对于fscanf()
函数,格式说明符要严格得多,因为没有参数提升
允许使用scanf()
到&#34;工作&#34;等格式。对于%d
或char
,bool
呼叫被提升为int
。 printf()
函数传递参数的地址,如果地址引用的是与格式说明符所预期的大小不一致,将导致未定义的行为 - 例如,未解释的更改另一个变量。
答案 3 :(得分:5)
bool
是一种与int
不同的数据类型,它可能只是一个字节。
scanf
不是类型安全函数,您使用%d
转换说明符告诉它需要指向int 的指针,而scanf
没有知道你已经通过pointer to bool
而不是指向int 的指针的方式。然后,您将获得未定义的行为。
clang 编译生成警告:
source_file.c:8:16: warning: format specifies type 'int *' but the argument has type 'bool *' [-Wformat]
scanf("%d", &x);
~~ ^~
source_file.c:13:16: warning: format specifies type 'int *' but the argument has type 'bool *' [-Wformat]
scanf("%d", &y);
~~ ^~
答案 4 :(得分:3)
所有其他答案在技术上都是正确的,但并不能真正帮到你。
你的主要问题不是x或y,而是你自己无法调试最琐碎的编程问题。这很容易修复 - 启用编译器警告(如果使用gcc
,添加-Wall
选项)。编译器会告诉你这样的错误,还有很多错误。无需每次都进行stackoverflow:)
答案 5 :(得分:0)
考虑以下计划
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int z, s;
printf("int z: %p\nint s: %p\n", &z, &s);
bool x, y;
printf("bool x: %p\nbool y: %p\n", &x, &y);
return 0;
}
输出:
int z: 0028FF3C
int s: 0028FF38
bool x: 0028FF37
bool y: 0028FF36
现在,在z
和s
之间存在4个字节的差异,这是我案例中int
的大小。
在x
和y
之间,只有1个字节的差异。
现在有了这一行:
scanf("%d", &y);
您告诉我%d
到scanf
您需要一个4字节长的输入,int
。
如果int
来自地址y
并且输入0028FF36
,则0x0001
将存储0
,0028FF37
将是x
存储在65535
。这就是y
的地址。
您可以使用其他输入值进行检查。例如,如果您将0xFFFF
提供给x
0xF
,则255
将为USER()
,即CURRENT_USER()
十进制。
答案 6 :(得分:0)
或者可能(如果输入字符串包含true或1将返回1
- 否则0
)
int getBool(char *message)
{
char input[20];
printf("%s", message);
fgets(input, 20, stdin);
return !!strstr(strlwr(input), "true") || strtol(input, NULL, 10);
}