c++ - 如果我从 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++ 标准(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 字符集)保证
- ... 在源和执行基本字符集中,上述十进制数字列表中 0 之后的每个字符的值都应比前一个字符的值大一。吨
如果您将这些值用作例如对应于符号的 50'2'
作为数组的索引,则该索引将超出数组的范围。
要在数组的可接受索引范围内获得正确的索引,您应该使用表达式
single_digits[*num - '0']
在这种情况下,您将拥有例如 if*num
是符号'2'
*num - '0' == '2' - '0' == 50 - 48 == 2
推荐阅读
- python - 如何从 django 中的多个模型中查询
- java - 如何在 Java 中为新文件自动提交 git
- c++ - 如何将 Boost DLL 放入 CMake 安装目录?
- excel-formula - 如何在GETPIVOTDATA中引用包含monthnameshort的单元格范围
- ssh - VS Code:通过 SSH 从 Windows 自动上传(部署)文件
- elasticsearch - 如何根据分片数计算 Elasticsearch 的分片数?
- python - python中基于response.status_code的循环函数
- html - 用 css 和 html 将图表放在半页中
- laravel - 无法解决依赖性 [参数 #0
- javascript - 错误类型错误:fs_1.statSync 不是函数