首页 > 解决方案 > 如果我从 single_digits [*num - '0'] 中删除'0',为什么这个程序会崩溃)

问题描述

我找到了如何将数字转换为单词的程序,但在字符串数组 single_digits[*num - '0']) 中我无法理解的一件事;为什么在数组索引中删除“0”时程序会崩溃这里“0”的用途是什么

我正在使用带有代码块窗口的 GCC // C 程序以用单词打印给定的数字。该程序处理从 0 到 9999 的数字

#include <stdio.h> 
      #include <string.h> 
      #include <stdlib.h> 

// A function that prints given number in words */

    void convert_to_words(char *num) 
    { 
        int len = strlen(num); // Get number of digits in given number 

        /* Base cases */
        if (len == 0) { 
            fprintf(stderr, "empty string\n"); 
            return; 
        } 
        if (len > 4) { 
            fprintf(stderr, "Length more than 4 is not supported\n"); 
            return; 
        } 

// The first string is not used, it is to make 
//array indexing simple 
                 char *single_digits[] = { "zero", "one", "two", 
                                "three", "four","five", 
                                "six", "seven", "eight", "nine"}; 

// The first string is not used, it is to make 
            array indexing simple */
        char *two_digits[] = {"", "ten", "eleven", "twelve", 
                                "thirteen", "fourteen", 
                                "fifteen", "sixteen", 
                                "seventeen", "eighteen", "nineteen"}; 

// The first two string are not used, they are to make 
 array indexing simple*/
            char *tens_multiple[] = {"", "", "twenty", "thirty", "forty",             "fifty", 
                                "sixty", "seventy", "eighty", "ninety"}; 

             char *tens_power[] = {"hundred", "thousand"}; 

// Used for debugging purpose only */
        printf("\n%s: ", num); 

// For single digit number */
          if (len == 1) { 
            printf("%s\n", single_digits[*num - '0']); 
            return; 
           } 

// Iterate while num is not '\0' */
          while (*num != '\0') { 

 // Code path for first 2 digits */
            if (len >= 3) { 
                if (*num -'0' != 0) { 
                    printf("%s ", single_digits[*num - '0']); 
                    printf("%s ", tens_power[len-3]); // here len can be 3 or 4 
                } 
                --len; 
            } 

  // Code path for last 2 digits */
            else { 
 // Need to explicitly handle 10-19. Sum of the two digits is 
 used as index of "two_digits" array of strings */
                if (*num == '1') { 
                    int sum = *num - '0' + *(num + 1)- '0'; 
                    printf("%s\n", two_digits[sum]); 
                    return; 
                } 

   // Need to explicitely handle 20 */
                else if (*num == '2' && *(num + 1) == '0') { 
                    printf("twenty\n"); 
                    return; 
                } 

 // Rest of the two digit numbers i.e., 21 to 99 */
                else { 
                    int i = *num - '0'; 
                    printf("%s ", i? tens_multiple[i]: ""); 
                    ++num; 
                    if (*num != '0') 
                        printf("%s ", single_digits[*num - '0']); 
                } 
            } 
            ++num; 
        } 
    } 
     /* Driver program to test above function */
    int main(void) 
    { 
        convert_to_words("9923"); 
        convert_to_words("523"); 
        convert_to_words("89"); 
        convert_to_words("8989"); 

        return 0; 
    }

标签: c++arraysindexingcharc-strings

解决方案


根据 C++ 标准(8.5.1.1 下标)

1 后缀表达式后跟方括号中的表达式是后缀表达式。其中一个表达式应为“T 数组”类型的左值或“指向 T 的指针”类型的纯右值,另一个应为无作用域枚举或整数类型的纯右值...

在此代码段中

      if (len == 1) { 
        printf("%s\n", single_digits[*num - '0']); 
        ret

如果这个表达式

single_digits[*num - '0']

重写喜欢

single_digits[*num]

则子表达式的类型为char*,即整数类型),其对应符号为以下集合之一'0', '1', '2', '3', '4', '5', '6', '7', '8''9'.

在内部,这些符号作为整数存储在 ASCII 中,例如数字48, 49, 50, 51, 52, 53, 54, 55, 56, 57

标准(5.3 字符集)保证

  1. ... 在源和执行基本字符集中,上述十进制数字列表中 0 之后的每个字符的值都应比前一个字符的值大一。吨

如果您将这些值用作例如对应于符号的 50'2'作为数组的索引,则该索引将超出数组的范围。

要在数组的可接受索引范围内获得正确的索引,您应该使用表达式

single_digits[*num - '0']

在这种情况下,您将拥有例如 if*num是符号'2'

*num - '0' == '2' - '0' == 50 - 48 == 2

推荐阅读