传递结构的二维数组

时间:2016-02-24 22:51:56

标签: c pointers multidimensional-array struct

我从数组中处理卡片类型结构。

struct card deck[DECKSIZE];  //The deck is an array of cards structures

我正在使用2D数组。一组卡片类型结构数组

struct card allHands[hands][cards];

我使用此函数将deck和数组作为指针传递给数组的参数。我还改变了甲板指针的位置,以模拟卡片在传递给玩家时丢失卡片。

void dealHands(struct card *deck, struct card **handArray, int hands, int cards){

    int players;
    int cardCount;
    int passCard = 0;
    struct card * thisDeck;

    thisDeck = deck;

    for(players = 0; players < hands; players++){
        for(cardCount = 0; cardCount < cards; cardCount++){
            handArray[players][cardCount] = thisDeck[passCard];
            passCard++;
        }   
    }
    deck = (deck + passCard);   
}   

我用c编程了很长时间,所以我觉得这就是你做原型的方法吗?

    void dealHands(struct card[], struct card*[], int, int);

这就像我主要是如何实现这个功能的骨架。

int main(int argc, char *argv[])
{
    /* Declare and initialize variables  */

    int hands = atoi(argv[HANDSINPUT]);  //How many players 
    int cards = atoi(argv[CARDSINPUT]);  //How many cards per hand  
    struct card deck[DECKSIZE];  //The deck is an array of cards structures

    struct card allHands[hands][cards];

    //Builds the deck
    //Shuffles deck with a RNG and swapping every card

    int players;
    int cardCount;
    int passCard = 0;   


    dealHands(deck, allHands, hands, cards);


}

我在编译期间得到以下2个语句

警告:从不兼容的指针类型[默认启用]传递'dealHands'的参数2   dealHands(甲板,所有手,手,牌);   ^

注意:预期'struct card **'但参数类型为'struct card()[(sizetype)(cards)]'  void dealHands(struct card [],struct card [],int,int);       ^

当我需要在一个函数中调用它们时,我总是搞砸指针和数组。所以我不确定我的逻辑在哪里有缺陷。我在哪里传递地址而不是值,反之亦然?

2 个答案:

答案 0 :(得分:7)

将数组作为函数参数传递时最重要的是:无法将数组传递给函数

说,仔细阅读以下内容。 (为简单起见,我将使用int,但当然您也可以使用其他类型。)

但是你可以传递一个数组的“指向第一个元素的指针”。幸运的是,C会自动进行转换。更重要的是,除了三个例外(sizeof_Alignof&运算符)之外的所有例外,C都会自动将数组的名称转换为这样的指针。这通常被称为“数组衰减到指向第一个元素的指针”。

但这种衰退不是递归的。因此,如果将2D数组传递给函数,它会衰减到指向1D数组的指针:

int a[1][2];    // 1 = outer dimension, 2 = inner

传递给函数

void f(int a[1][2]);

变为

int (*a)[2]   // pointer to array of inner dimension

或者,可以明确使用指针语法

void f(int (*a)[2]);

所有案例的a类型均为int (*)[2]。注意括号!您使用哪种语法基本上是个人偏好。我更喜欢所有维度的数组语法,因为它更清楚地记录了意图。

除最外层尺寸外,您必须始终传递所有尺寸。这仅用于文档而不是必需的(参见下面的示例)。

在函数内部,使用普通的index-operator:

int t, i;    // index variable for ouTer, Inner
a[t][i];

请注意,这可以应用于更高维度的数组。对于1D阵列,这实际上也适用。只需删除内部维度:

int a[1];

衰败到

int *a;

(我只使用常量12来对尺寸进行编号;当然,您可以使用所需的尺寸。)

如果要传递长度可变的数组(VLA,_variable length array),则必须将除最外层维度以外的所有维度传递给函数:

f(int inner, a[][inner]);

但更好的检查等是通过所有维度:

f(int outer, int inner, a[outer][inner]);

答案 1 :(得分:-2)

所有这一切可能都有点难以理解,但一旦你试验它就很容易。你看,你永远不能将整个数组作为参数传递(我的意思是你可以通过传递每一个元素,但这不是重点)。数组基本上是一种表格。如果它是1D,你有一排盒子。如果它是2D,你有一个盒子表。如果它是3D,你有一个箱子的幼崽(e / oid)。你可以做的是利用数字如何在内存中布局并使用指针算法。这很简单。

好的,让我们走吧 -

我们假设我们有一个函数set_up_array,它将指向2D数组的指针作为参数。

void set_up_array(int **array, int row_size, int column_size){
    for(int i = 0; i < row_size; i++){
        for(int j = 0; j < column_size; j++){
            *((int*)array + i*row_size + j) = i + j + k;
        }
    }
}

这可能会让你感到害怕,但请留在我身边。

现在,想象一下您作为表传递的2D数组。它有行,然后它有列。你会怎么去这样一张桌子的下一个元素?好吧,你有你的元素的索引,你发现它,对吧?这正是我们在这里所做的事情 我将首先解释我们将数组转换为int *的原因。这很简单。每当我们进行指针数学运算时,C编译器都会尝试简化我们的工作(就像一个真正的萌芽......),所以我们只是添加元素的数量,而不是将地址添加到指针中,并且基于此,C编译器会自动找出我们想要的地址。现在,问题在于,C编译器通过找出指针所指向的类型的大小来计算出来。所以,为了让我们的生活变得简单,并且让C编译器开心,我们将它转​​换为int *,这意味着,从这里开始,无论我们添加什么,都会添加到初始地址,就像它一样。 INT * S。 现在让我们回到桌面比喻。我们知道行号和列号 enter image description here你可能想要记住的一件事是,这张图片的列和行标签反转了

为了让我们的生活更加简单,让我们切换到笛卡尔视图(图形视图,带有x和y坐标)。让我们说x是水平的,而y是垂直的。然后我们可以将arrray写为
array[y][x]
这意味着我们想要的元素是x*row_size + y元素。 我们基本上可以添加到我们函数中的指针,并取消引用它,就像它已经完成,就在那里,我们使用了i和j。