繁体   English   中英

通过函数将指针传递给数组

[英]Passing Pointer To An Array Of Arrays Through Function

在代码中有一个指向数组的指针,即NameList。 我希望逐个打印指针(NameList)中每个数组的内容。 以下代码无法执行任务。 PLS。 救命。

int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};

int *NameList[] = {Data1, Data2, Data3};
main()
{  Function(NameList); }

Function(int *ArrayPointer)
  {
    int i, j, index=0;
    for (i=0; i < 3; i++)
      {
        for (j=0; j < 2; j++)
          {
             //It does not print the data
             printf("\nName: %s",  ArrayPointer[index++]);
          } 
        index=0;         //Counter reset to 0
        ArrayPointer++;  //Pointer is incremented by one to pick next array in the pointer
      }
  }
print("code sample");

该问题原始海报的另一个注释:

我在Turbo C中完成了一个pacman游戏。我正在抛光一些图形例程,以便它可以轻松地重复使用。 这只是为了帮助和理解这个概念而创建的一个小样本。 代码中的所有数据实际上都是sprite的char数组。 现在我只想调用一个传递指针的函数,以便指针中的每个数组都被绘制到屏幕上。 如何修改此代码来处理此问题? 我实际上是在这里。

点燃它,再一次,你只需几分钟就能击败我。 (如果我没有孩子继续醒来......)

啊,到底是怎么回事。 也许这对某些人来说仍然有用。


哦,只是为了解决这个问题:

  • 诸如int a [4]之类的数组为其数据分配内存空间。
  • 指针(例如int * p)只为指向内存中另一个点的指针分配内存空间。
  • 这就是为什么我们可以在数组上使用sizeof并获得完整的内存占用,而不是指针。

除了那个小小的区别之外,int []和int *之间确实没有太大的区别。 (考虑有多少人声明* main(int argc,char ** argv)vs main(int argc,char * argv []) 。)


注意:这里的所有内存地址都是虚构的。 我只想说明一点。

鉴于:

int Data1[] = {10,11};
int Data2[] = {20,22};
int Data3[] = {30,33};

我们现在有3块内存。 说:

0xffff0000-0xffff0003  with a value of (int)(10)
0xffff0004-0xffff0007  with a value of (int)(11)

0xffff0008-0xffff000b  with a value of (int)(20)
0xffff000c-0xffff000f  with a value of (int)(22)

0xffff0010-0xffff0013  with a value of (int)(30)
0xffff0014-0xffff0017  with a value of (int)(33)

哪里:

Data1 == & Data1 [0] == 0xffff0000
Data2 == & Data2 [0] == 0xffff0008
Data3 == & Data3 [0] == 0xffff0010

,我不会在这里进入big-endian vs little-endian字节排序!

是的,在这种情况下,Data1 [2] == Data2 [0]。 但你不能依赖你的编译器在内存中放置内容,就像我在这里放置它们一样。

下一个:

int *NameList[] = {Data1, Data2, Data3};

所以我们现在有另一块内存。 说:

0xffff0018-0xffff001b  with a value of (int*)(0xffff0000)
0xffff001c-0xffff001f  with a value of (int*)(0xffff0008)
0xffff0020-0xffff0023  with a value of (int*)(0xffff0010)

哪里:

NameList == & NameList [0] == 0xffff0018

请注意,NameList是int **类型,而不是int *类型!

然后我们可以写:

void Function(int **ArrayPointer)
{
  for ( int i=0; i < 3;  i++ )
    for ( int j=0; j < 2; j++)
      printf("Name: %d\n",  ArrayPointer[i][j] );
}

int main() {  Function(NameList); }

ArrayPointer解析为(int **)0xffff0018。

ArrayPointer [0] == *((int **)0xffff0018)==(int *)(0xffff0000)== Data1。

ArrayPointer [0] [1] == *((*(int **)0xffff0018)+ 1)==(int)*((int *)0xffff0000 + 1)==(int)*(int *)0xffff0004 = = Data1 [1]。


您可能想要查看指针算术:array [N] == *(array + N)

main必须返回一个类型。 您忘记将“int”作为返回类型(禁止在C ++中使用隐式int)。

话虽如此,我不确定你的意思

// It does not print the data
printf("\nName: %s",  ArrayPointer[index++]);

ArrayPointer[index++]将在参数列表中定义,返回一个int 怎么会存储一个名字 它会存储一个整数

再说一次,你说不能用那个特定的参数调用那个函数(双关语)。 让我们来看看你的类型:

int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};

int *NameList[] = {Data1, Data2, Data3};

Data1      Data2      Data3      NameList
int[2]     int[2]     int[2]     int*[3]

与您所说的相反,NameList 不是指向数组数组的指针。 我觉得我需要告诉你那将是什么:

int (*NameList)[N][M] = Some3DimensionalArray;

这根本没有意义。 那你有什么?

Data1 = array of 2 int
Data2 = array of 2 int
Data3 = array of 2 int
NameList = array of poiners to int

就是你得到的。 然后将NameList传递给想要指向int的指针的Function。 当你在main调用Function时它必须已经失败! 我不知道你在Function中的那个name是什么意思。 但是如果你想打印存储在指向的数组中的整数(通过指向它们的第一个元素的指针),你可以这样做(尽可能多地保留你的代码):

// don't forget the return type, mate. Also see below
void Function(int **ArrayPointer)
  {
    int i, j, index=0;
    for (i=0; i < 3; i++)
      {
        for (j=0; j < 2; j++)
          {
             // It does not print the data. It is not a string, 
             // but an int!
             printf("\nName: %d\n",  ArrayPointer[i][index++]);
          } 
        index=0;         //Counter reset to 0
        // no need to increment the pointer. that's what the indexing by i 
        // above does
        // ArrayPointer++;  
      }
  }

我一直在讲道人们问问指针和数组之间的区别。 编写正确的代码至关重要。 我希望我能提供帮助。 最后,只是关于int[]int*之间的区别。 第一个是不完整的数组类型,而第二个是完整类型(指向int的指针):

typedef int Single[]; // array of indeterminate size.
typedef int *Pointer; // pointer to int

Single s1 = { 1, 2, 3, 4 }; // works!
Pointer s2 = { 1, 2, 3, 4 }; // no no, doesn't work. s2 wants an address

s2的类型现在有一个与int []不同的类型,因为你初始化了那个类型不完整的数组,数组s1在定义后变得完整。 它的类型为int[4] 但是,在参数列表中,存在一个特殊规则,它将导致任何数组类型(甚至完整的数组!)等同于指向其第一个参数的指针。 从而:

void f(int *a) <=> void f(int a[]) <=> void f(int a[42]);
void f(int (*a)[42]) <=> void f(int a[][42]) <=> void f(int a[13][42])
// ...

那是因为你不能按值传递数组。 编译器滥用它来使数组类型等同于指向其第一个元素的指针。 同样处理功能:

void f(int a()) <=> void f(int (*a)())

因为你不能通过值传递函数(呵呵,甚至对我来说都没有意义),编译器滥用它来使参数列表中的函数类型等效于指向该函数类型的指针。

我在你的程序中做了一些更正,请找到并进行比较。 我知道答案太迟了。 但我今天看到了这一点。

int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};

int *NameList[] = {Data1, Data2, Data3};

main()
{  
  Function(NameList); 
}

Function(int *ArrayPointer)
{ 
    int i, j, index=0;
    for (i=0; i < 3; i++)
      {
        for (j=0; j < 5; j++)
          {
             //It does not print the data
             printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));
         index++;
          } 
        index=0;         //Counter reset to 0
      }
  }

说明:

当您将NameList传递给Function作为指向整数的指针时,传递的是数组的第一个元素的地址,恰好是Data1(数组的地址)。 但由于此地址以整数数组保存,因此将其视为整数。 为了使它的行为类似于数组的地址(或者,对于指向int的指针),您需要将其转换为(int *)。 多数民众赞成我所做的:

printf("\\nName: %d\\n", *((int *)ArrayPointer[i] + index));

int Data1[]

有类型的

int *

int *NameList[]

有类型的

int **

那里有一个二维数组。 你很可能意味着:

Function(int **ArrayPointer)

在这方面,ANSI C / C89 / C99函数具有显式返回类型(或void ),例如

int main() { ... }
void Function() { ... }

ArrayPointer指向的值是int ,而不是字符串。 从而

printf("\nName: %s",  ArrayPointer[index++]);

应该写成别的东西。

第三件事:代码中的index == j 因此可以删除index以支持j

ij在这里可能不是很好的变量名,因为ArrayPointer不是描述某事物列表的名称。

如果您需要更多帮助,请发布您要查找的内容,因为您的代码中存在多个错误(和奇怪的内容)。

根据你的“ 答案 ”判断(你真的应该编辑原帖并添加这些信息),你可能想要这样的东西:

void draw_all_sprites(Sprite *sprites, size_t num_sprites)
{
    Sprite *cur_sprite;
    size_t i;

    for(i = 0; i < num_sprites; ++i)
    {
        draw_sprite(cur_sprite);
        ++cur_sprite;
    }
}

一个相当简单的for循环来迭代数组中的元素。

Paramod,

是否有一个你需要调用的函数,它需要一些东西

void drawSprite(int *data, int rows, int cols)

然后,您需要将所有数据放在一块内存中。 在您的示例中,编译器为每一行分配一个单独的块,然后为另一个块分配三个指向行的指针。 因此,阵列保持在4个不同的位置。

你需要的是一个多维数组而不是数组数组。 像这样初始化您的数据:

int data[3,2] = {{10,10},{20,20},{30,30}};

然后你可以像这样调用你的函数:

drawSprite(&data[0,0], 3, 2);

使用多维数组将所有元素放在一个内存块中。 优点是,您可以将piointer传递给第一个元素,并且您知道所有其他元素的位置。 缺点 - 所有行都分配了相同的大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM