C - 通过函数传递数组

时间:2010-11-24 18:55:51

标签: c arrays pointers char

我有以下......

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

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

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

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

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

这是该功能的另一部分。

4 个答案:

答案 0 :(得分:2)

keySorter内,keys是指向char数组数组的指针。这意味着要获取char数组以用于strcpy,您需要对指针进行反洗,然后使用数组访问来选择数组。

E.g。

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);
}

答案 1 :(得分:1)

你声明了自动变量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 };

答案 2 :(得分:1)

这是(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()之间的重要区别。在第一个中,因为传递了指向2D数组的指针,访问数组的代码必须首先使用(*keys)[i][j]取消引用指针,而在第二个中,直接传递数组并使用直接访问符号{{1很好。

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

keys[i][j]

显示的代码干净利落地编译。当我在gcc -O -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ -Wold-style-definition xx.c -o xx 中尝试使用keys[i][j]时,它抱怨'错误:分配中的类型不兼容。

您还可以修改keySorter()以使用keySorter()(当然,您也应该strcpy()):

#include <string.h>

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

如果/当你写的时候:

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]是第三个数组,依此类推。指针可能衰减得足以让你最终在每个数组的第一行上写BLAH,但是你最终会遇到核心转储或其他类似的问题,因为你没有在主程序中分配足够的数组。

答案 3 :(得分:0)

键已经是一个指针,所以你不必做这个keySorter(&amp; keys);只需要keySorter(键);