关于CS50 Pset3 atoi递归实现代码的技术疑问求助
CS50 Pset3 atoi递归实现疑问解答
先看修正后的代码(移除冗余全局变量)
#include <cs50.h> #include <ctype.h> #include <math.h> #include <stdio.h> #include <string.h> int convert(string input); int main(void) { string input = get_string("Enter a positive integer: "); for (int i = 0, n = strlen(input); i < n; i++) { if (!isdigit(input[i])) { printf("Invalid Input!\n"); return 1; } } // Convert string to int printf("%i\n", convert(input)); } int convert(string input) { int n = strlen(input); if (n == 0) { return 0; // 原全局变量number无实际作用,直接返回0即可 } char last_digit = input[n - 1]; int converted_last_digit = last_digit - '0'; input[n-1] = '\0'; return converted_last_digit + 10 * convert(input); }
疑问解答
全局变量
number为什么会变成输入数字?
它根本不会变,这个变量是完全冗余的。代码里没有任何语句修改它的值,自始至终都是初始值0。递归的结果是靠函数返回值的计算累积出来的,和这个全局变量无关——哪怕删掉它,把base case改成return 0,程序运行结果完全一致。10 * convert(input)的作用是什么?为什么是10?
乘以10是为了给高位数字腾出数位空间。递归从右往左处理每一位数字,当拿到当前位时,之前递归返回的结果是左侧已处理好的数字组合,乘以10相当于把这些数字整体“左移”一位(提升一个数位),给当前数字留出个位位置。比如先处理3得到结果3,再处理2时,2要放在十位,所以用2 + 10*3=23,以此类推。用10是因为我们用的是十进制计数法,每一位的权重是10的幂次。输入"123"为何返回123而非321?
拆解递归执行和返回的过程就清楚了:- 第一层
convert("123"):取最后一位3,字符串改为"12",返回3 + 10*convert("12") - 第二层
convert("12"):取最后一位2,字符串改为"1",返回2 + 10*convert("1") - 第三层
convert("1"):取最后一位1,字符串改为"",返回1 + 10*convert("") - 第四层
convert(""):触发base case,返回0
从最底层倒推计算返回值: - 第三层返回:
1 + 10*0 = 1 - 第二层返回:
2 + 10*1 = 12 - 第一层返回:
3 + 10*12 = 123
每次都是把当前数字加到“已处理数字的个位”,已处理数字通过乘10提升了数位,所以最终结果是正确的123。
- 第一层
递归中数字如何存储传递?为何返回完整数字?
数字是通过递归调用的返回值链来传递和累积的。每一层递归都会把当前处理的数字,和下一层返回的“左侧已组合好的数字”(乘10后)相加,把结果返回给上一层。最底层(空字符串)返回0作为初始值,然后逐层往上叠加计算,最终把所有数位按正确的权重组合成完整数字,而非只返回最后处理的单个数字。
内容的提问来源于stack exchange,提问作者Harr
相关产品推荐
相关产品推荐

