【问题标题】:Using char as array index in C?在C中使用char作为数组索引?
【发布时间】:2011-10-10 22:00:45
【问题描述】:

我有这个代码:

int main(){

  char vector[52];
  char i;

  /* initialize the vector */
  for (i ='a'; i < 'z'; i++){
    vector[i] = i - 'a' + 1;
  } 
  // vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26


  for (i ='A'; i <= 'Z'; i++){
    vector[i] = i - 'A' + 27;
  }
  // vector is like vector['A'] = 27, vector['B'] = 28 .. vector['z'] = 52

  for (i ='a'; i <= 'z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  } 

  for (i ='A'; i <= 'Z'; i++){
    printf("letter %c : %d \n", i, vector[i]);
  }

  return 0;
}

输出:

letter a : 1 
letter b : 2 
letter c : 3 
letter d : 4 
letter e : 5 
letter f : 6 
letter g : 7 
letter h : 8 
letter i : 9 
letter j : 10 
letter k : 11 
letter l : 12 
letter m : 13 
letter n : 14 
letter o : 15 
letter p : 16 
letter q : 17 
letter r : 18 
letter s : 19 
letter t : 20 
letter u : 21 
letter v : 22 
letter w : 23 
letter x : 24 
letter y : 25 
letter z : 0 
letter A : 27 
letter B : 28 
letter C : 29 
letter D : 30 
letter E : 31 
letter F : 32 
letter G : 33 
letter H : 34 
letter I : 35 
letter J : 36 
letter K : 37 
letter L : 38 
letter M : 39 
letter N : 40 
letter O : 41 
letter P : 42 
letter Q : 43 
letter R : 44 
letter S : 45 
letter T : 46 
letter U : 47 
letter V : 48 
letter W : 49 
letter X : 50 
letter Y : 51 
letter Z : 52 
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x50)[0xc25df0]
/lib/i386-linux-gnu/libc.so.6(+0xe5d9a)[0xc25d9a]
./a.out[0x8048547]
[0x343332]
======= Memory map: ========
00110000-0012a000 r-xp 00000000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
0012a000-0012b000 r--p 00019000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
0012b000-0012c000 rw-p 0001a000 08:01 131939     /lib/i386-linux-gnu/libgcc_s.so.1
00a19000-00a1a000 r-xp 00000000 00:00 0          [vdso]
00aa4000-00ac0000 r-xp 00000000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00ac0000-00ac1000 r--p 0001b000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00ac1000-00ac2000 rw-p 0001c000 08:01 131898     /lib/i386-linux-gnu/ld-2.13.so
00b40000-00c9a000 r-xp 00000000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9a000-00c9b000 ---p 0015a000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9b000-00c9d000 r--p 0015a000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9d000-00c9e000 rw-p 0015c000 08:01 131911     /lib/i386-linux-gnu/libc-2.13.so
00c9e000-00ca1000 rw-p 00000000 00:00 0 
08048000-08049000 r-xp 00000000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
08049000-0804a000 r--p 00000000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
0804a000-0804b000 rw-p 00001000 08:01 40062      /home/valter/Documents/Complexidade/recursivo/a.out
0846f000-08490000 rw-p 00000000 00:00 0          [heap]
b7772000-b7773000 rw-p 00000000 00:00 0 
b7782000-b7785000 rw-p 00000000 00:00 0 
bfa50000-bfa71000 rw-p 00000000 00:00 0          [stack]
Aborted

我不明白为什么会给出这个错误信息。 我应该有一个这样的向量:

vector['a'] = 0, vector['b'] = 1,  .., vector['z'] = 26, vector['A'] = 27, vector['B'] = 28, .., vector['Z'] = 52

我知道我有这个向量,但错误随之而来。 如何解决这个问题?

【问题讨论】:

标签: c++ c arrays vector


【解决方案1】:

因为“Z”不等于“z”。

'Z' 等于 90,你的向量只有 52 个元素。你的最高指数是 51,所以你基本上是越界了!

例如当你这样做时

  for (i ='A'; i <= 'Z'; i++)
  {
    vector[i] = i - 'A' + 27;
  }

这是您的第一次迭代的样子:

vector[65] = 65 - 65 + 27; // <-- Wrong index !

【讨论】:

    【解决方案2】:
    for (i ='A'; i <= 'Z'; i++){
        vector[i] = i - 'A' + 27;
    }
    

    不做你认为它做的事。 'A' 表示字符 A 的 ASCII 值,即 65;您的索引立即超出范围。

    【讨论】:

    • 这并不意味着“ASCII 值”。它是平台编码中的任何数值“A”。
    【解决方案3】:
    char vector[52];
    

    所以,vector 的可访问索引是 0 到 51。但是 -

    for (i ='A'; i <= 'Z'; i++) // 'A' = 65 and 'Z' = 90
    {
        printf("letter %c : %d \n", i, vector[i]);
    }
    

    向量上没有这样的索引,结果越界异常。

    【讨论】:

      【解决方案4】:
        char vector[52];
        for (i ='a'; i < 'z'; i++){
          vector[i] = i - 'a' + 1;
        } 
      

      'a' 是 97。你的数组只有 52 长。你几乎用你的第一个可执行语句破坏了数组。

      我怀疑你的意思是这样的

          vector[i-'a] = something;
      

      (虽然我不太确定“某物”可能是什么。)

      【讨论】:

        【解决方案5】:

        首先,附注:您的第一个 for 循环还需要包含“z”。因此:

        for (i ='a'; i <= 'z'; i++){
        

        在 C 中,数组不是从任何值到任何值的映射。它们只是一个数组(或连续列表),从索引 0 开始。当你说

        char vector[52];
        

        表示您有一个大小为 52 的数组。该数组的有效索引是 0 到 51。但是,当您编写像 'a' 这样的字符时,它实际上只是一个数字,即字符 a 的 ascii 代码(即 0x61,即 61 十六进制)。您正在使用的最高索引是 'z',即 122。因此,您的数组需要有效的索引 122,因此必须具有 至少 123 的大小。

        所以你的代码变成了这样:

        int main(){
        
          char vector[123];
          char i;
        
          /* initialize the vector */
          for (i ='a'; i <= 'z'; i++){
            vector[i] = i - 'a' + 1;
          } 
          // vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26
        
        
          for (i ='A'; i <= 'Z'; i++){
            vector[i] = i - 'A' + 27;
          }
          // vector is like vector['A'] = 27, vector['B'] = 28 .. vector['z'] = 52
        
          for (i ='a'; i <= 'z'; i++){
            printf("letter %c : %d \n", i, vector[i]);
          } 
        
          for (i ='A'; i <= 'Z'; i++){
            printf("letter %c : %d \n", i, vector[i]);
          }
        
          return 0;
        }
        

        另外,你的问题也有矛盾。你先说你有:

        // vector is like vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26
        

        然后你说:

        我应该有一个这样的向量:

        vector['a'] = 0, vector['b'] = 1,  .., vector['z'] = 26, vector['A'] = 27, vector['B'] = 28, .., vector['Z'] = 52
        

        如果你想让vector['a']从0而不是1开始,你应该把你的公式从vector[i] = i - 'a' + 1;改成vector[i] = i - 'a';

        【讨论】:

        • 对不起我的矛盾,我的意思是:vector 就像 vector['a'] = 1, vector['b'] = 2 .. vector['z'] = 26 而不是第二种情况
        猜你喜欢
        • 1970-01-01
        • 2010-11-02
        • 1970-01-01
        • 2021-12-25
        • 2019-04-12
        • 2019-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多