【问题标题】:What is the difference between a pointer to a pointer and the addressof a pointer in C?C中指向指针的指针和指针的地址有什么区别?
【发布时间】:2013-04-21 15:33:30
【问题描述】:

将变量 x 初始化为 char ** 和将变量 x 初始化为 char * 然后使用 & 有什么区别参考吗?这个问题来自以下查询:

我在看 ma​​n 3 strtol 函数。函数签名为:

long strtol(const char *restrict str, char **restrict endptr, int base);

所以,为了传递 endptr 变量,我设置了一个变量:

char **endptr;

但是当我将它传递给函数时,它总是返回 NULL,即使在传递给 strtolstr 类似于 abc 的情况下.
即:

         char ** endptr;
         long exitval = strtol(args[1], endptr, 10); /* try to get the val */
         if (endptr != NULL) { /* it wasn't a valid base-10 number */

然而,当我将 endptr 的初始化方式更改为:

char *endptr;

然后将 endptr 作为 &endptr 传递给函数,endptr 设置正确。即:

         char * endptr;
         long exitval = strtol(args[1], &endptr, 10); /* try to get the val */
         if (endptr != NULL) { /* it wasn't a valid base-10 number */

在这两种情况下,我都认为我传递的是 一个指向 char 数组中第一个字符的指针的指针,但事实上一个方法有效而另一个方法无效我的理解是不正确的。

为什么一种方法有效而另一种无效?我误会了什么?

【问题讨论】:

  • 你是如何初始化**endptr的?
  • strtol 的典型用法可能是 char* endptr = NULL; long l = strtol(buf, &endptr, 10);,Linux strtol(3) 手册页提供了完整示例。
  • @minitech,编辑了 Q 以包含所用代码的两个版本。
  • 嗯,在新版本中,endpointer 没有指向任何东西(它是未初始化的)。它应该指向一个字符指针。

标签: c


【解决方案1】:

我会试一试的。

函数strtol 想要它可以写入的地址。

当你声明时

char *ptr;

您有一个名为 ptr 的变量,当您传递其地址时,strtol 可以写入该位置,然后您可以通过查看变量的内容来使用该值。

当你声明时

char **ptr;

并且只是传递它的值,首先你可能传递了一个未初始化的值,strtol 将尝试写入,其次,即使你初始化它,你也只是传递它的内容 - strtol 将修改它指向的位置,而不是变量本身的内容。

【讨论】:

  • 感谢您的回答。有点跟进:当你说“你传递的只是它的内容 - strtol 将修改它指向的位置,而不是变量本身的内容”,你的意思是我传递了 ** 的未初始化值指针?
  • @Nate - 是的。如果不传递变量的地址,strtol 就无法修改它,就像将整数变量作为参数传递给函数时,将该参数设置为另一个值不会改变该值返回时函数外的变量。
  • 明白了,谢谢!这清除了我正在考虑的另一个问题:参数-如果当您将参数传递给函数时,该函数知道参数的地址以及参数的值,并且从您的答案中推断,它看起来就像函数只知道一个或另一个。
  • @Nate - 没错 - 如果您传递地址,您可以在函数内部使用 * 取消引用并更改该地址的值。传入的地址本身就像一个局部变量,改变它对函数外部没有影响,就像任何其他参数一样。
【解决方案2】:

首先,您没有为指向指针的指针赋值,它是您传递给 strtol 的未初始化值,其次您定义了一个指针,然后您得到了它的地址,所以您正在传递 endptr 的地址。

另一种思考方式是,第一个示例是在内存中定义一个位置来保存指向指针的指针,但该内存未设置为任何内容,然后您将垃圾传递给 strol。第二个是在内存中定义一个保存指针的位置,然后获取内存位的地址,然后将其传递给 strol。

【讨论】:

    【解决方案3】:

    来自手册页:

    如果 endptr 不为 NULL,strtol() 将第一个无效字符的地址存储在 *endptr 中。

    在第一种情况下,您将endptr 的值传递给初始化为0 的strtol(),因此strtol() 不会将第一个无效字符的地址存储在*endptr 中。

    在第二种情况下,您将endptr的地址传递给strtol(),它不是0,因此如果发现无效字符,它将不会返回NULL。

    【讨论】:

    • 谢谢。您的回答很有道理——我不清楚传递地址与值的确切区别。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2017-06-19
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多