Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我能';你不能传递链的地址吗?斯特托_C - Fatal编程技术网

C 为什么我能';你不能传递链的地址吗?斯特托

C 为什么我能';你不能传递链的地址吗?斯特托,c,C,我有这段代码,函数strtol接收一个双指针,假设字符串“prueba”是一个指针,指向字符串第一个元素的内存地址(这是整个链的同一内存地址),然后就好像它在传递指针的dir,我不知道我是否解释过,无论如何,它不工作:/在这里给出警告 ret = strtol(str, &prueba, 10); 长整数字符串(常量字符*str,字符**endptr,整数基) strtol将str中字符串的初始部分转换为长整型 根据给定的基数计算的值。 “endptr”his是对char*类型对象的引

我有这段代码,函数strtol接收一个双指针,假设字符串“prueba”是一个指针,指向字符串第一个元素的内存地址(这是整个链的同一内存地址),然后就好像它在传递指针的dir,我不知道我是否解释过,无论如何,它不工作:/在这里给出警告

ret = strtol(str, &prueba, 10);
长整数字符串(常量字符*str,字符**endptr,整数基)

strtol将str中字符串的初始部分转换为长整型 根据给定的基数计算的值。 “endptr”his是对char*类型对象的引用,其值由函数设置为数值后str中的下一个字符

#包括
#包括
int main()
{
char str[30]=“2030300这是测试”;
char prueba[20];
char*ptr;
长ret;
printf(“\nLa cadena inciales:%c%s%c\n”,34,str,34);
ret=strtol(str和ptr,10);
printf(“\n数字(无符号长整数)为%ld\n”,ret);
printf(“字符串部分为|%s |\n”,ptr);
ret=strtol(str和prueba,10);
printf(“\n概率:%c%s%c\n”,34,普鲁巴,34);
返回(0);

我发现这里有一个很大的误解需要解决:指针和数组不一样。指针是告诉你如何找到其他东西的东西;其他东西可以是一个东西,或者是足够的未初始化空间来容纳一个东西,或者是一个块中的一堆东西。数组是一个东西块,而v这不是一个指向一块东西的指针。你可以把
[0]
放在每一块东西后面,最后得到一个东西,这与本次讨论无关

为什么不像传递给函数甚至赋值那样,它不会退化为表示其第一个元素地址的
char*
?因为C标准说它不会——它精确地定义了“数组退化为指向其第一个元素的指针”的三个例外其中一个规则是当数组是
&
操作符的操作数时,这样你就可以得到一个指向你要问的东西的指针,而不是其他一些虽然相关但不是这个东西的东西

因此,您没有将
char**
传递到
strtol
中。您传递的是指向数组的指针。虽然在某些情况下这可能没问题,但它不在这里,因为函数希望将
char*
放在您告诉它放一个的位置;如果您尝试说“将它放在这个
char[]
”,它不会执行您想要的操作。它会尝试将
char*
填充到您的
char[]
中,您将得到未定义的行为

如需进一步阅读,请参阅comp.lang.c常见问题和解答


哦,顺便说一句,如果您告诉GCC:将
-Wincompatible指针类型
或更好的是,类似
-Wall-Werror
(取决于编译器的建议)之类的东西传递给编译器,GCC将对此发出警告——它将产生一个大致如下的警告:

/path/to/main.c:在函数“main”中:
/path/to/main.c:17:23:警告:从不兼容的指针类型[-Wincompatible指针类型]传递'strtol'的参数2
ret=strtol(str和prueba,10);
^
在/usr/include/stdio.h:29:0中包含的文件中,
from/path/to/main.c:1:
/usr/include/stdlib.h:166:6:注意:应为'char**restrict',但参数的类型为'char(*)[20]'
long(strtol(const char*(const restrict),char**(char**)restrict(char end)PTR,int(u)base);;

当然,确切的文本可能有所不同,但要点是相同的。

&prueba
是指向20个
字符的数组的指针。
&prueba
不是
字符**
。它是
字符(*)[20]
。也就是说,它是指向数组的指针。您需要声明为:
char*prueba;
但是如果我声明char*prueba,它是指向数组的指针。就像char-prueba[20]您永远不希望将数组或指向数组的指针作为
strtol
的第二个参数传递。传递指针的地址才有意义。
strtol
的第二个参数的目的是,它可以“返回”指向停止转换整数的位置的指针。它“返回”指向原始字符串的指针(在您的示例中为
str
)。也就是说,在调用
strtol(str,&ptr,10)之后
,您的指针
ptr
是返回的指针值,它指向
str
中的某个位置。如果您传递数组
prueba
,您希望发生什么情况?@EmiliOrtega No.
char*
不是数组。尽管有时它们的行为类似。正如您“询问”的那样对于它:您不能将索引运算符(resp,+或-)应用于数组。它看起来似乎(听起来像是吹毛求疵,但一旦您理解了这一点,您就理解了C中的数组)。它不起作用的原因(除了类型问题)仅仅是因为您无法更改数组本身的值(数组本身没有像指针那样的价值,它只是元素)。最后:C信息页面列出了建议的警告。这些警告包括
-Wall-Wextra-Wconversion
。就个人而言,我建议更多一些。
long\u EXFUN(…
?),嗯,从来没有看到过这样的消息。@Olaf是的,我没有那么严格地正确(也就是说,我是从语法的角度讲的--
inta[2];a[0];
是有效的语法,就像
int*a;a[0];
一样。我认为相似性是造成混淆的原因,但我会把它弄清楚。为什么它不起作用呢?哎呀,是的,我一定要把它弄清楚。这就是我的意思。)“把它放在这个
char[]
”,但它…并没有真正被理解。WRT
long\u EXFUN
——这就是我编译代码时编译器输出的内容。我不知道它从哪里来。从路径上看,我假设是lin
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char str[30] = "2030300 This is test";
    char prueba[20];
    char *ptr;
    long ret;
    printf("\nLa cadena inicial es: %c%s%c\n",34,str,34);


    ret = strtol(str, &ptr, 10); 
    printf("\nThe number(unsigned long integer) is %ld\n", ret);
    printf("String part is |%s|\n", ptr); 

    ret = strtol(str, &prueba, 10);
    printf("\nProbando: %c%s%c\n",34,prueba,34);

   return(0);