【问题标题】:C - passing arrays through functionsC - 通过函数传递数组
【发布时间】:2010-11-24 18:55:51
【问题描述】:

我有以下...

void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys]) {}

int main ()
{
  char keys[NumberOfKeys][LengthOfKeys] = {};
  keySorter (&keys);
}

所以,我有这个,它编译得很好,但我得到了我想要的。 keys[][] 已经用= {}; 进行了初始化,所以它是空的,但它应该在函数内部被填充。

第一个元素被放入函数中,剩下的...?我观察了函数 STRCPY,它将数据放入 keys[][] 并且它具有正确的源值,但目标值似乎是垃圾(或者至少它组成了看起来像垃圾的字符)。

strcpy(*keys[i], "BLAH");

这是函数的另一部分。

【问题讨论】:

  • 您是如何尝试读取 keySorter 中的值的?
  • 另外,您是否填写了keys
  • 不,我实际上是在尝试填充键[][]。它是空的。

标签: c arrays pointers char


【解决方案1】:

keySorter 内部,keys 是一个指向char 数组数组的指针。这意味着要获取char 的数组以与strcpy 一起使用,您需要取消对指针的引用,然后使用数组访问来选择一个数组。

例如

strcpy((*keys)[i], "test");

您不能使用*keys[i],因为优先规则意味着首先应用[],而keys 不是指向数组第一个元素的指针,而是指向数组本身的指针。

顺便说一句,对于您正在做的事情,将keySorter 声明为获取指向字符数组的指针并让普通数组到指针衰减发生在函数的参数上更为传统。

void keySorter(char keys[][LengthOfKeys]);

void keySorter(char (*keys)[LengthOfKeys]);

在这种情况下,您可以简单地执行strcpy(keys[i], "blah"),因为keys 是一个指针char 的数组数组。

调用:

int main ()
{
  char keys[NumberOfKeys][LengthOfKeys] = {};
  keySorter(keys);
}

【讨论】:

    【解决方案2】:

    这是有效的 (C99) 代码 - 如果您的窗口超过 100 列宽,则输出是整齐的(如果您的窗口较窄,请将 32 调整为较小的数字):

    #include <stdio.h>
    
    enum { NumberOfKeys = 20, LengthOfKeys = 32 };
    
    static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys])
    {
        size_t k = 0;
        for (size_t i = 0; i < NumberOfKeys; i++)
            for (size_t j = 0; j < LengthOfKeys; j++)
                (*keys)[i][j] = ++k & 0xFF;
    }
    
    static void dumpKeys(char keys[NumberOfKeys][LengthOfKeys])
    {
        for (size_t i = 0; i < NumberOfKeys; i++)
        {
            for (size_t j = 0; j < LengthOfKeys; j++)
                printf("%02X ", keys[i][j] & 0xFF);
            putchar('\n');
        }
    }
    
    int main(void)
    {
        char keys[NumberOfKeys][LengthOfKeys] = {};
        printf("Before:\n");
        dumpKeys(keys);
        keySorter(&keys);
        printf("After:\n");
        dumpKeys(keys);
    }
    

    请注意keySorter()dumpKeys() 中用于访问数组的符号之间的关键区别。第一种,因为传递了一个指向二维数组的指针,所以访问数组的代码必须首先用(*keys)[i][j]解引用指针,而第二种,直接传递数组,直接访问符号keys[i][j]就可以了.

    当我使用(MacOS X 10.6.5 上的 GCC 4.2.1)编译时:

    gcc -O -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
        -Wold-style-definition xx.c -o xx  
    

    显示的代码编译干净。当我尝试在keySorter() 中使用keys[i][j] 时,它抱怨“错误:分配中的类型不兼容”。

    您也可以修改keySorter() 以使用strcpy()(当然,您也应该使用#include &lt;string.h&gt;):

    static void keySorter(char (*keys)[NumberOfKeys][LengthOfKeys])
    {
        for (size_t i = 0; i < NumberOfKeys; i++)
            strcpy((*keys)[i], "BLAH");
    }
    

    在索引到数组之前,您仍然必须取消引用指向数组的指针。

    如果/当你写了:

    strcpy(keys[i], "BLAH");
    

    那么你应该得到编译器警告(如果你没有得到更好的编译器,或者至少想办法让你的编译器发出大量警告),但keys[0] 的值是第一个数组在keys指向的数组集合中,然后keys[1]是第二个数组,keys[2]是第三个数组,以此类推。指针可能会衰减到足以导致您最终在每个数组的第一行上写入 BLAH,但您最终会遇到核心转储或其他此类问题,因为您没有在主程序中分配足够的数组。

    【讨论】:

      【解决方案3】:

      你声明了自动变量keys,但没有往里面放任何东西,所以它会包含垃圾值。

      是的,您正确地传递了数组,因为调用和声明的函数参数类型匹配。但是您将 指针传递给一个 char 数组的数组,而不是一个简单的指向数组第一个 char 元素的指针。也许你应该这样做:

      void keySorter(char keys[NumberOfKeys][LengthOfKeys])
      {...}
      
      int main(void)
      {
          char  keys[NumberOfKeys][LengthOfKeys];
          keySorter(keys);
      }
      

      这使您可以非常简单地访问数组元素:

      for (int i = 0;  i < NumberOfKeys;  i++)
      {
          for (int j = 0;  j < LengthOfKeys;  j++)
          {
              ... keys[i][j] ...
          }
      }
      

      附录

      添加显式初始化值足以将数组初始化为全零(即所有'\0' char 值):

          char  keys[NumberOfKeys][LengthOfKeys] = { 0 };
      

      【讨论】:

      • keys 初始化为零。
      • @Steve Jessop:这是 C,从技术上讲,一对空括号不是有效的初始化程序。
      • @Charles:好的,好吧,然后它不会编译(或使用诊断编译并执行特定于实现的操作)。但它可能不会把它当作垃圾:-)
      【解决方案4】:

      keys 已经是一个指针,所以你不必这样做 keySorter (&keys);只放 keySorter (keys);

      【讨论】:

      • key 本身是错误的类型,一个 指向 char 的指针,但该函数需要一个 指向 char 数组数组的指针
      • @Loadmaster:不,它是char 的二维数组,衰减为pointer to array of char。所以这里的 OP 和这个答案的语法都是正确的。
      • 问题中的语法是正确的,这个答案中的语法是not正确的。 &amp;keys 是指向 char 数组数组的指针(正如函数所预期的那样),但 keys 衰减为指向 char 数组的指针(数组 char 数组的第一个元素) .
      • @Charles Bailey:你是对的,这正是我想说的。
      猜你喜欢
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 2013-05-15
      • 2021-02-24
      • 1970-01-01
      相关资源
      最近更新 更多