效果很好。
#include <stdio.h>
#include <stdlib.h>
int main(void){
char number[]= "a123.45", *strtod_eptr;
double num;
num=strtod(number, &strtod_eptr);
if (strtod_eptr == number){
printf("Error: no number found.\n");
}
else{ printf("%f\n", num+7);
}
return 0;
}不起作用。strtod()中的第二个参数已更改类型。
#include <stdio.h>
#include <stdlib.h>
int main(void){
char number[]= "a123.45", **strtod_epptr;
double num;
num=strtod(number, strtod_epptr);
if (*strtod_epptr == number){
printf("Error: no number found.\n");
}
else{
printf("%f\n", num+7);
}
return 0;
}编译器警告未初始化的strtod_epptr,但没有编译错误。
strol_test.c:7:5: warning: ‘strtod_epptr’ is used uninitialized in this function [-Wuninitialized]在if()语句中,程序崩溃(seg错误)。
编译器命令(在两种情况下):
gcc -Wall -pedantic -o "strol_test" "strol_test.c"这一切为什么要发生?为什么gcc抱怨未初始化的**strtod_epptr,而对(类似的未初始化的?) *strtod_eptr完全没问题?在取消引用**strtod_epptr时会出现什么问题?AFAIK:
char *ptr;
...strtod(...,&ptr)应该与
char **ptr;
...strtod(...,ptr)但显然不是这样的。我遗漏了什么?
发布于 2018-02-03 06:54:44
想想记忆吧。
当您编写char *str时,您要求编译器为字符指针分配内存。现在,当您将str的地址发送给函数时,作为&str,字符串中的值可以更改。
现在换一种方式。
当您编写char **str时,您要求编译器为指向字符指针的指针分配内存。这意味着没有为char指针分配内存。如果现在取消引用该指针,它将不会指向任何有意义的指针。
现在,您将str传递给了strtod()。该函数现在执行*str = something()。但是那个地方在记忆中是不存在的。该存储桶不是创建和分配的。
以后,总是传递已经存在的变量的地址。如果不是,则函数没有可以更新的变量...
发布于 2018-02-03 06:58:19
strtod需要一个双指针(指向指针的指针),因为它想告诉用户它停止读取的位置。所以它必须改变指针指向的位置,因此它不能接受(单个)指针,它必须接受指向指针的指针。
手册组
#include double strtod(const char *nptr,char **endptr);
..。
返回值
这些函数返回转换后的值(如果有)。
如果endptr不是NULL,则将指向在转换中使用的最后一个字符之后的字符的指针存储在 is引用的位置中
这意味着您通过endptr传递的指针必须指向有效的char-pointer,这就是为什么
char number[]= "a123.45", *strtod_eptr;
num=strtod(number, &strtod_eptr);因为&strtod_eptr返回strtod_eptr变量的地址,所以它工作得很好,它返回指向指针的指针。然后,strtod可以使用指向指针的指针来更改原始指针(strtod_eptr)的指向位置。
在内部,strtod会这样做:
double strtod(const char *nptr, char **endptr)
{
size_t i;
double converted_value;
...
if(endptr != NULL)
{
// i is the index the character after the last
// character used in the conversion
*endptr = &(nptr[i]);
}
return converted_value;
}当endptr指向一个有效的位置时,取消对它的引用不会成为问题。
然而,
char number[]= "a123.45", **strtod_eptr;
num=strtod(number, strtod_eptr);不起作用,因为strtod_eptr是一个uninitialzed指针,它不会特别指向任何地方。当strtod执行*endptr = &(nptr[i])时,它正试图在未定义的内存位置写入一个值,这是未定义的行为,segfault就是这种行为的一种表现。
然而,这将会起作用:
char number[]= "a123.45", *end, **strtod_eptr;
strtod_eptr = &end;
num=strtod(number, strtod_eptr);因为在这种情况下,strtod_eptr将指向一个有效的位置。
https://stackoverflow.com/questions/48591705
复制相似问题