修改qsort比较函数内容是否违规?字符串转换是否触发未定义行为?
qsort比较函数中使用strtod/atof是否合规?
核心结论
使用strtod、atof这类字符串转数值函数不属于修改传入对象的行为,不会触发未定义行为,完全可以在qsort的比较函数中使用,不需要自行编写排序例程。
具体解释
关于“不得修改传入对象”的要求
qsort要求比较函数不能修改的是传入的两个对象——也就是你要排序的char*数组中的元素(包括指针本身,以及指针指向的字符串内容)。而strtod、atof只是读取字符串的内容并转换成数值,不会对原字符串做任何写入操作,完全符合“不修改传入对象”的约束。关于“同一对象调用返回一致结果”的要求
只要被排序的字符串在排序过程中保持不变(没有被其他线程或代码修改),每次对同一个字符串调用strtod/atof都会得到相同的数值结果,自然满足比较函数的一致性要求。
示例代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 用于qsort的比较函数:按字符串对应的数值排序 int cmp_num_str(const void *a, const void *b) { const char *s1 = *(const char **)a; const char *s2 = *(const char **)b; double n1 = strtod(s1, NULL); double n2 = strtod(s2, NULL); if (n1 < n2) return -1; if (n1 > n2) return 1; return 0; } int main() { char *num_strs[] = {"5.2", "0.8", "10.1", "3.0"}; size_t len = sizeof(num_strs) / sizeof(num_strs[0]); qsort(num_strs, len, sizeof(char*), cmp_num_str); for (size_t i = 0; i < len; i++) { puts(num_strs[i]); } return 0; }
注意事项
- 如果存在无效的数值格式字符串,
strtod会返回0并设置errno,你可以根据需求添加错误处理逻辑,但这不属于qsort合规性的问题。 - 排序过程中要保证被排序的字符串不会被外部修改,否则会破坏比较结果的一致性。
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

