C: 数组的方括号之间可以有字符吗?
C: Is a char possible between the square brackets of an array?
直到今天我的回答都是:"No, there has to be an integer in it, that determines the position of the array."
但现在我从我们的教授那里得到了这段代码片段(用于 base64 解码),我还在 Whosebug 和其他网站上找到了它:
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
void build_decoding_table1() {
int i;
decoding_table = malloc(256);
for (i = 0; i < 64; i++)
decoding_table[(unsigned char) encoding_table[i]] = i;
}
让我吃惊的是:
decoding_table[(unsigned char) encoding_table[i]] = i;
这里发生的事情——至少我认为是这样发生的——例如当 i
== 0
时,我们得到 encoding_table
- 的第一个位置数组,所以 encoding_table[0]
== 'A'
。转换为 unsigned char
,所以它仍然是 'A'
。所以我们有:decoding_table['A'] = 0;
确定数组位置的字符对我来说是新的。这是如何运作的?是否使用了 ASCII-table 的等价整数(65
而不是 'A'
)?还是我误解了这段代码的作用,我把我当成一个完全的菜鸟?
数组位置需要一个整数,但 char
只是一个 8 位整数。实际上,任何可以添加到指针的内容都可以用在括号中,因为 array[5]
与 *(array+5)
是一样的。
文字 'A'
是 - 根据您系统的字符集,表示为整数值,例如65
在 ASCII 中。顺便说一句——文字的数据类型是 integer
,而不是 char
,但这在这里并不重要。
你的编码table是char
的数组,如果你的系统默认signed char
for char
,那么整数值65会被存储为signed char
,即一个 8 位有符号整数值。
反过来,如果你写 decoding_table[(unsigned char) encoding_table[i]]
,那么 encoding_table[i]
中的有符号 8 位整数值 65
被转换为无符号的 8 位整数值,仍然给出 65
。转换为 unsigned 是个好主意,因为 8 位有符号 char 可能是负数,例如 decoding_table[-10]
。这将是未定义的行为,因为它越界访问了数组。
所以你的假设是正确的:你可以将字符文字视为整数值,因此你可以将它用作数组索引。
直到今天我的回答都是:"No, there has to be an integer in it, that determines the position of the array."
但现在我从我们的教授那里得到了这段代码片段(用于 base64 解码),我还在 Whosebug 和其他网站上找到了它:
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
void build_decoding_table1() {
int i;
decoding_table = malloc(256);
for (i = 0; i < 64; i++)
decoding_table[(unsigned char) encoding_table[i]] = i;
}
让我吃惊的是:
decoding_table[(unsigned char) encoding_table[i]] = i;
这里发生的事情——至少我认为是这样发生的——例如当 i
== 0
时,我们得到 encoding_table
- 的第一个位置数组,所以 encoding_table[0]
== 'A'
。转换为 unsigned char
,所以它仍然是 'A'
。所以我们有:decoding_table['A'] = 0;
确定数组位置的字符对我来说是新的。这是如何运作的?是否使用了 ASCII-table 的等价整数(65
而不是 'A'
)?还是我误解了这段代码的作用,我把我当成一个完全的菜鸟?
数组位置需要一个整数,但 char
只是一个 8 位整数。实际上,任何可以添加到指针的内容都可以用在括号中,因为 array[5]
与 *(array+5)
是一样的。
文字 'A'
是 - 根据您系统的字符集,表示为整数值,例如65
在 ASCII 中。顺便说一句——文字的数据类型是 integer
,而不是 char
,但这在这里并不重要。
你的编码table是char
的数组,如果你的系统默认signed char
for char
,那么整数值65会被存储为signed char
,即一个 8 位有符号整数值。
反过来,如果你写 decoding_table[(unsigned char) encoding_table[i]]
,那么 encoding_table[i]
中的有符号 8 位整数值 65
被转换为无符号的 8 位整数值,仍然给出 65
。转换为 unsigned 是个好主意,因为 8 位有符号 char 可能是负数,例如 decoding_table[-10]
。这将是未定义的行为,因为它越界访问了数组。
所以你的假设是正确的:你可以将字符文字视为整数值,因此你可以将它用作数组索引。