C语言中atoi与atof转换结果赋值int变量的差异问题
两种字符串转int写法的差异
两种写法存在明确差异,核心来源是atoi和atof两个函数的设计定位、返回值类型完全不同:
atoi的函数原型为int atoi(const char *str),原生功能就是把字符串转换为int类型整数:转换时会跳过开头的空白字符,逐字符读取数字内容,遇到第一个非数字字符就停止转换,返回值本身就是int类型,赋值给int变量a时类型完全匹配,无额外隐式转换。atof的函数原型为double atof(const char *str),原生功能是把字符串转换为double类型双精度浮点数:支持识别小数、科学计数法格式的数字串,返回值是8字节浮点型。把它的返回值直接赋值给int变量a时,会触发C语言的隐式类型转换,直接丢弃浮点数的小数部分,仅保留整数段赋值。
两者的结果差异在特定输入下会非常明显:
举个例子:如果
word存储的字符串是"1e3":
- 用
atoi转换时,读到字符e就判定为非数字停止转换,最终返回值为1- 用
atof转换时,会识别科学计数法得到double值1000.0,隐式转int后a拿到的值是1000,两者结果相差1000倍。如果
word存储的是"123.999":
atoi读到.就停止,返回123atof先转成123.999,截断小数后同样得到123,这时候两者结果碰巧一致,但逻辑路径完全不同。
是否可用atof/atoi给int变量存值
两种方式的可行性要分开说:
- 对于
atoi:这是该函数的设计内用法,只要字符串对应的整数值处于当前运行环境下int类型的取值范围内(32位int通常范围是-2^31 ~ 2^31-1),完全可以直接把返回值存入int变量。但要注意atoi没有错误处理能力:如果字符串是非数字开头、或者数值超出int范围,函数行为是未定义的,不会返回明确的错误标识,生产场景更建议用带错误检测的strtol函数替代。 - 对于
atof:语法上允许把它的返回值赋值给int变量,多数编译器只会抛出类型转换的警告,不会阻止编译,但强烈不推荐这么用:- 隐式浮点转int的过程存在精度丢失、越界的未定义风险,当转换得到的double值超出int取值范围时,最终赋值结果完全不可预期
- 浮点数转换本身有额外的性能开销,为了转整数走浮点转换逻辑完全没有必要
- 当字符串对应整数长度超过double的有效精度范围(double仅能保证53位二进制位的整数精确表示),转换过程就会出现精度损失,最终赋值给int的值可能和实际字符串代表的数值不符。
内容的提问来源于stack exchange,提问作者Niv
相关产品推荐
相关产品推荐

