我对为什么此代码成功为我提供正确的输入感到困惑。
In [154]: some_json = {
...: "vidName": "Foo",
...: "vidInfo.0.size.length": 10,
...: "vidInfo.0.size.width": 10,
...: "vidInfo.0.quality": "Good",
...: "vidInfo.1.size.length": 7,
...: "vidInfo.1.size.width": 3,
...: "vidInfo.1.quality": "Bad",
...: "vidInfo.2.size.length": 10,
...: "vidInfo.2.size.width": 2,
...: "vidInfo.2.quality": "Excelent"
...: }
In [155]: some_json
Out[155]:
{'vidName': 'Foo',
'vidInfo.0.size.length': 10,
'vidInfo.0.size.width': 10,
'vidInfo.0.quality': 'Good',
'vidInfo.1.size.length': 7,
'vidInfo.1.size.width': 3,
'vidInfo.1.quality': 'Bad',
'vidInfo.2.size.length': 10,
'vidInfo.2.size.width': 2,
'vidInfo.2.quality': 'Excelent'}
In [156]: from flatten_json import unflatten_list
...: import json
...: nested_json = unflatten_list(json.loads(json.dumps(some_json)), '.')
In [157]: nested_json
Out[157]:
{'vidInfo': [{'quality': 'Good', 'size': {'length': 10, 'width': 10}},
{'quality': 'Bad', 'size': {'length': 7, 'width': 3}},
{'quality': 'Excelent', 'size': {'length': 10, 'width': 2}}],
'vidName': 'Foo'}
为什么我打印** y时不起作用,我假设将指针x传递给bintest并存储在指针y中,然后应将其称为** y来打印输入值?
答案 0 :(得分:3)
这是不确定的行为。
它由于以下原因而起作用:
&x
是x
指针的地址。由于指针的大小通常至少为int
的大小,因此scanf("\n%d", &x);
会简单地覆盖指针。然后,您将该指针(其值现在是用户键入的值)传递到bintest
您的编译器应该给您至少两个警告,例如:
'scanf':格式字符串'%d'需要类型为'int *'的参数,而可变参数1的类型为'int **'
'printf':格式字符串'%d'需要类型为'int'的参数,而可变参数1的类型为'int *'
这两个警告都是错误,您不应忽略它们。
答案 1 :(得分:3)
您应该开始打开编译器警告并予以注意。您的简短摘要会产生3!警告。
$ gcc main.c -Wall -Wextra
main.c: In function ‘main’:
main.c:12:19: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int **’ [-Wformat=]
scanf("\n%d", &x);
~^ ~~
main.c: In function ‘bintest’:
main.c:18:23: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("\ny: %d", y);
~^ ~
%ls
main.c:19:5: warning: control reaches end of non-void function [-Wreturn-type]
}
^
您的程序具有未定义的行为,并且可以通过应有的方式表现出来。
正确的代码应该是
scanf("\n%d", x);
...
printf("\ny: %d", *y);
如果不想返回任何内容,则将bintest
声明为void函数。
我对为什么此代码成功为我提供正确的输入感到困惑。
您正在将读取的值存储在指针x
中,这会导致内存泄漏,因为您丢弃了malloc
调用。您可以删除malloc
调用,并且程序的行为相同。 (可能。它确实具有未定义的行为)。
答案 2 :(得分:1)
您没有在所需的x IF中存储整数值;您要求用户输入并用用户提供的值覆盖了指针x。现在,该指针x指向用户给出的内容。
稍后,您将x传递给该函数并打印该值:这样您就可以得到用户提供的内容。
但是您不能取消引用它。 x指向用户提供的值。那是什么值?您知道这是一些有效的内存位置吗?
有关scanf的最佳阅读帮助文档。
如果您真的想使用用户提供的值存储整数x,则代码类似于
int x; scanf(...&x)。
然后将&x传递给该函数。
答案 3 :(得分:0)
支持@Jabberwocky所说的话
test.c: In function ‘main’:
test.c:7:12: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int **’ [-Wformat=]
7 | scanf("\n%d", &x);
| ~^ ~~
| | |
| | int **
| int *
test.c: In function ‘bintest’:
test.c:11:16: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
11 | printf("\ny: %d", y);
| ~^ ~
| | |
| int int *
| %ls
test.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]
12 | }
| ^
当我尝试使用CLion IDE(gcc(GCC)9.1.1 20190503(Red Hat 9.1.1-1),C11)编译代码时出现了这个问题,尽管我还不太了解。我希望它能有所帮助,并且有人可以进一步解释。
答案 4 :(得分:0)
如果要扫描x指向的值,请像这样使用 x :scanf("\n%d", x)
。要打印您刚刚放置的值,然后像这样传递{strong> x :bintest(x);
,但像这样{<1>}打印 * y : >
printf("%d", *y);
与scanf("\n%d", &x);
x = scan;
与您想要的scanf("\n%d", x);
相同。
因此,在此示例*x = scan;
中,您给scanf &x ,它是x本身的地址。这样做意味着scanf将更改x的值,从而更改x指向的对象。
函数scanf想要一个地址到其放置值的位置。因此,要将其放在x指向的位置,您只需传递 x 。
具有相同值的原因是因为您只是像这样传递{strong> x :scanf("\n%d", &x);
并像这样打印 y :{{ 1}}。在此示例中,y只是x的副本。
如果要测试这些功能如何使用指针,请尝试使用此代码。我以99为例。
bintest(x);
您应该获得类似于以下的输出:
printf("%d", y);