1

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

我在看man 3 strtol函数。函数签名是:

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

因此,为了传递endptr变量,我设置了一个变量:

char **endptr;

但是当我将它传递给函数时,它总是返回 NULL,即使在传递给strtol的str类似于abc的情况下也是如此。IE:

         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设置正确。IE:

         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 array 中第一个 char 的指针的指针,但是一种方法有效而另一种方法无效的事实并不表明我的理解是不正确的。

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

4

3 回答 3

3

我会开枪的。

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

当你声明

char *ptr;

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

当你声明

char **ptr;

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

于 2013-04-21T15:45:12.367 回答
1

在第一个中,您没有为指向指针的指针赋值,它是您传递给 strtol 的未初始化值,在第二个中,您正在定义一个指针,然后您正在获取它的地址,因此您正在传递endptr 的地址。

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

于 2013-04-21T15:46:22.287 回答
0

从手册页:

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

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

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

于 2013-04-21T15:51:30.113 回答