C语言字符串转整数函数问题:我的实现存在哪些错误?
咱们来一步步拆解你这段代码里的问题,每个问题都附上对应的修复思路:
字符转数值的逻辑完全错误
你这里写的*n = *str;只是把字符串第一个字符的ASCII值直接赋值给了n,比如输入字符串"123",*str是字符'1',它的ASCII值是49,所以*n会被设为49,而不是我们想要的123。正确的做法应该是遍历字符串的每个字符,逐步累加计算数值:*n = 0; for (i = 0; i < len; i++) { *n = *n * 10 + (*(str+i) - '0'); }这里
*(str+i) - '0'是把字符形式的数字转成对应的整数数值(因为ASCII里'0'-'9'是连续的)。循环中重复调用
strlen导致效率低下strlen函数每次调用都会从字符串开头遍历到末尾来计算长度,你在循环条件里每次都调用它,会让时间复杂度从O(n)变成O(n²)(n是字符串长度)。建议先把字符串长度存到一个变量里,再用这个变量做循环条件:int len = strlen(str); for (i = 0; i < len; i++) { // ... 循环逻辑 }未处理空字符串的情况
如果传入的是空字符串"",strlen(str)会返回0,循环不会执行,之后执行*n = *str时,访问的是字符串的终止符'\0',这属于未定义行为,而且空字符串本身也无法转成有效的int值。应该在开头就判断空字符串:if (str == NULL || *str == '\0') return 0;isdigit的参数使用不规范isdigit函数要求传入的参数是unsigned char类型或者EOF,如果你的系统里char是有符号类型,当字符的ASCII值大于127时,转成int会变成负数,这时候调用isdigit会导致未定义行为。正确的做法是把字符强制转换成unsigned char:if (isdigit((unsigned char)*(str+i)) == 0) return 0;缺少正负号的处理(可选但实用)
目前你的函数只能处理纯数字字符串,但标准的int类型是支持正负号的(比如"-123"或"+456")。如果需要支持这个场景,可以在开头判断第一个字符是否是'-'或'+',然后调整遍历的起始位置和最终数值的符号。未处理数值溢出的情况
当字符串表示的数字超过了int类型的取值范围时(比如32位int的最大值是2147483647,输入"2147483648"),直接累加会导致整数溢出,这也是未定义行为。可以在每次累加前检查是否会溢出,比如:#include <limits.h> // ... if (*n > (INT_MAX - (*(str+i) - '0')) / 10) { // 溢出了,返回错误 return 0; }
内容的提问来源于stack exchange,提问作者张海军

