CS50 Credit问题求助:10位以上卡号计算异常及函数叠加问题
CS50 Credit问题技术求助
我是编程新手,在解决CS50 Credit问题时遇到以下技术问题:
firstCase函数负责从卡号倒数第二位开始,每隔一位数字乘2后拆分求和,该函数在卡号≤10位时结果正常,但输入11位及以上卡号时计算结果出现异常,请问可能的原因是什么?secondCase函数的结果似乎自动与firstCase的结果叠加(这是最终需要的逻辑,但我并未编写相关叠加代码),请问是哪段代码导致了这个现象?
目前因一直得到INVALID结果,我注释了最终的判断逻辑,仅通过printf测试firstSum和total的值,恳请各位提供技术指导。
代码片段
#include <cs50.h> #include <stdio.h> long getNumber(void); int cardDigits(long number); long returnDivisor(int cardLength); long firstCase(long workingcc); long secondCase(long workingcc); int conditions(long total); int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit); int main(void) { long number = getNumber(); int cardLength = cardDigits(number); long divisor = returnDivisor(cardLength); long workingcc = number; int firstDigit = number / divisor; int secondDigit = number / (divisor / 10); long firstSum = firstCase(workingcc); long total = secondCase(workingcc); //int checkConditions = conditions(total); //int cardResult = cardType(checkConditions, divisor, firstDigit, secondDigit); //if (cardResult == 1){ // printf("AMEX \n");} //else if (cardResult == 2){ // printf("MASTERCARD \n");} //else if (cardResult == 3){ // printf("VISA \n");} //else if (cardResult == 4){ // printf("INVALID \n");} } //Get card number from user long getNumber(void){ long n; do { n = get_long("card number "); } while (n <= 0); return n; } //Obtain card length and divisor int cardDigits(long number){ long n; n = number; int count = 0; while (n > 0) { n = n / 10; count++; } return count; } //Obtain divisor long returnDivisor(int cardLength){ long divisor = 10; for (int j = 0; j < cardLength - 2; j++) { divisor = divisor * 10; } return divisor; } //Obtain sum for first condition long firstCase(long workingcc){ int sum; workingcc = workingcc / 10; while (workingcc !=0) { int lastDigit = workingcc % 10; int timesTwo = lastDigit * 2; sum = sum + (timesTwo % 10) + (timesTwo / 10); workingcc = workingcc / 100; } return sum; } //Obtain sum for second condition long secondCase(long workingcc){ int sumb; while (workingcc > 0) { int lastDigit2 = workingcc % 10; sumb = sumb + lastDigit2; workingcc = workingcc / 100; } return sumb; } //Check total modulo 10 congruent to 0 int conditions(long total){ if (total % 10 == 0){ return 1; } else{ return 0; } } //Check results and print card type int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit){ if (checkConditions == 1 && divisor == 15 && (secondDigit == 34 || secondDigit == 37)){ return 1; } else if (checkConditions == 1 && divisor == 16 && (secondDigit == 51 || secondDigit == 52 || secondDigit == 53 || secondDigit == 54 || secondDigit == 55)){ return 2; } else if (checkConditions == 1 && divisor == (13 | 16) && firstDigit == 4){ return 3; } else{ return 4; } }
问题解答
问题1:firstCase函数11位及以上卡号计算异常的原因
firstCase中的sum变量未初始化,默认值是栈内存中的随机垃圾数据。卡号较短时,垃圾值可能刚好为0或影响微弱,但卡号越长,累加次数越多,垃圾值的干扰会被放大,导致结果完全错误。
解决方式:将int sum;改为int sum = 0;
问题2:secondCase结果自动叠加firstCase结果的原因
和问题1原理一致,secondCase中的sumb变量同样未初始化。由于栈内存的复用特性,它会直接继承firstCase执行后sum变量留下的数值,因此看起来像是自动完成了叠加。
解决方式:将int sumb;改为int sumb = 0;
额外需要修正的问题
cardType函数混淆了卡号长度和除数的概念:比如判断AMEX的条件divisor ==15是错误的,divisor是10的幂次(如15位卡号对应的除数是10^14),应该改为判断cardLength ==15,同理MasterCard和VISA的判断也需要替换为对cardLength的检查。cardType中的divisor == (13 | 16)是位运算,不是逻辑或,应改为(cardLength ==13 || cardLength ==16)。
内容的提问来源于stack exchange,提问作者TM-South-Sea
相关产品推荐
相关产品推荐

