调用hoti(char s[])函数,自己试了两种调用方式:
1.编译通过
char test[16] = "110"; char *ptest = test; ..... int htoi(char *ptest){....}
2.编译不通过
char *ptest = "110"; ..... int funtion(char *ptest)
分析原因如下:
首先对于字符串常量,比如这里的"110",编译器编译后会将它们放入只读节中:
.section .rdata,"dr"
LC1:
.ascii "110\0"
.text
这样在运行该程序时,会将只读节映射到只读的段中。如果运行时更改只读段中的数据,则会出现“一般保护性异常”,通常程序会abort。
再说char *ptest = "110"; 要先搞清楚“=”两边的类型,左边是一个char*类型的指针,右边是一个字符串常量,它所代表的类型是char const*, char const*是不能直接赋值给char*的,如果你用gcc编译器,会出现一个警告:
warning: deprecated conversion from string constant to 'char*'
这就像C++中,const& 不能赋值为非const&一样。不过编译器没有把它当成一个错误,而是一个警告。这时ptest就指向了处于只读节中的数据。
再看看char test[16] = "110";这代表什么呢? test[16]是个char类型的数组,这条代码的作用是将处于只读节中的数据copy到了一份在test[16]数组中了。函数原型是htoi(char s[]),实际上对于编译器而言,它等价于htoi(char* s),如果形参或实参是数组,它都会转化为指针。当你这样调用htoi(test)时,实参test是一个数组类型,这时它会退化成char*传递过去。谢谢网友lili_9809的回答。
#include <stdio.h>
int main(){ //char test[16] = "110"; char *ptest = "110"; int n = htoi(ptest); /* * 注意 char message1[] = "hello"与 char *message2 = "hello"的区别 * 前者初始化数组,后者是一个指针指向字符串常量,指针变量初始化为指向这个字符串常量的存储位置 * 传字符串地址应该: htoi(ptest) 而 htoi(*ptest)的意思是把字符串地址作为内存地址所存内容传递给函数, * 会发生意想不到的错误,即为段错误. */ printf("%d", n); return 0; } int htoi(char s[]){ int i = 0; if(s[i] == '0'){ i++; if(s[i] == 'x' || s[i] == 'X'); i++; } int hexdigit; int dd = 0; int hexflag = 0; while(s[i] != '\0'){ if(s[i] >= '0' && s[i] <= '9'){ hexdigit = s[i] - '0'; hexflag = 1; } else if(s[i] >= 'A' && s[i] <= 'F'){ hexdigit = s[i] - 'A' + 10; hexflag = 1; } else if(s[i] >= 'a' && s[i] <= 'f'){ hexdigit = s[i] - 'a' + 10; hexflag = 1; } else{ return 1; } dd = dd * 16 + hexdigit; i++; } return dd; }
参考资料:
1.http://topic.csdn.net/u/20110109/17/37461003-1e7e-4097-8d52-777bc9bfb8eb.html