从传递的指针打印指针值

时间:2019-07-01 06:31:13

标签: c pointers

我对为什么此代码成功为我提供正确的输入感到困惑。

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来打印输入值?

5 个答案:

答案 0 :(得分:3)

这是不确定的行为。

它由于以下原因而起作用:

&xx指针的地址。由于指针的大小通常至少为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);