发送指向函数的指针,而指针是指针数组的一部分

时间:2012-11-28 06:20:32

标签: c

我正在尝试发送指向函数的指针,但指针是指针数组的一部分

void func(A **pa)
{
     return;
}


A *pa;
pa=(A*)malloc(2*sizeof(A));

因此,数组pa[0]中的第一项很容易发送(因为它是指针指向的位置)

func(&pa);

但是现在我卡住了,我该如何发送第二件商品? pa[1]

我试过func(&pa + 1*sizeof(A));之类的东西 但它似乎没有用。

4 个答案:

答案 0 :(得分:2)

您正在寻找&pa[1]

func (&pa[1]);   // call function with second element of pointer array

顺便说一下,我不知道你是不是要分配一个只有两个指针的数组,但如果你是,则malloc是错误的。它应该是

pa = malloc (2 * sizeof(A*));  // note the addition of * after "A"

你正在做的是分配两倍于A的大小,可以想象这可能是几千字节长。指向这样一个对象的指针不需要那么多空间。

此外,在C中,我们不需要 - 也不应该 - 转换malloc()的返回类型。

答案 1 :(得分:2)

如果你想传递一个指向A数组的指针,你应该这样做:

func(&pa[0]); 
func(&pa[1]);

但是如果它是一个数组,你不应该只是传递指向数组本身的指针,以及数组的大小吗?这基本上只意味着第一行。

如果你想将指针传递给一个指针数组,你应该完全不同地完成它:

A **pa;
pa=(A**)malloc(2*sizeof(A*));

但是你还必须对每个A进行malloc并相应地改变Func。

另请注意,由于指针数学,func(&pa + 1*sizeof(A))不起作用:您只需要执行func(&pa + 1),编译器会处理其余部分以获取数组中的第二个成员。

答案 2 :(得分:2)

注意:此答案已更新,以反映4小时前的@hudac,OP(原始海报)的说明。提出的问题既有效又有趣。话虽如此,可能会有一些方法可以简化OP的代码,我会在提供原始问题的答案之后再看一下。

首先,根据OP最近的澄清,我将尝试通过给出A和func的示例定义来使问题代码更具体一些:

typedef struct { int x; int y;} A;

void func(A **ppa)
{
   printf("(%d,%d)\n",(*pa)->x,(*pa)->y);
}

然后,我将提供一些代码,为问题和答案提供适当的上下文:

void main() {
    A *pa;  
    pa = (A*) malloc(2 * sizeof(A));

    pa[0].x = 3;    pa[0].y = 4;
    pa[1].x = 13;    pa[1].y = 42;

    func(&pa);      
    //the answer to the question goes here
}

问题在于它要求一种方法将指针传递给指向动态分配的A pa数组的 second 元素的指针。 OP试过,成功地将指针传递给指向pafunc(&pa);)的第一个元素的指针,试图通过指针算法传递指向第二个元素的指针,当然这当然没有按预期工作。鉴于OP的代码,所给出的答案都没有接近正确!事实证明这是一个非常有趣的问题,因为func期望A **而不是A *会让事情变得如此复杂。在不了解OP遇到的问题的情况下,可以使事情变得更简单,但是这并不能解释为什么如此困难(事实上,不可能)使指针算法正确。

重新审视基础知识的一小部分:如果你有一个作业,你有一个左值(左边的表达式)和一个右值(右边的表达式);左值是具有地址的东西,并且右值具有赋值存储在左值的地址中的值。一个例子:x = 5;表达式可以具有左值和右值(例如x),或者它可以仅具有右值(例如5)。运营商&仅适用于左值,即适用于具有内存地址的内容,例如x等内容,但不适用于诸如5之类的内容。

回到问题:pa是A *类型,而func期望A **类型的参数。 OP没有问题找出如何调用func以便它可以与pa的第一个元素一起使用:

func(&pa);

请注意,我发现很难忍受这段代码以及评论这是对func的第一个元素的调用。函数func需要在pa [0](a.k.a。* pa)上运行,即类型A的东西,但由于func的定义方式,我们传递的是A **类型的**!稍后我将通过使用更合适的参数类型定义函数来解决此问题。现在,我将尝试使用我的工作。

OP和其他人发现调用func很难与pa的第二个元素一起工作的原因是需要的是一个指针表达式,其值保存了一点点的地址内存保存pa 的第二个元素的地址。没有这样的指针表示,因为第2个元素的地址不是 STORED 任何地方。 (道歉,如果大都会伤害你的眼睛:-)我需要尽可能清楚!)访问pa的第二个元素是通过指针算术,使用第一个元素的地址(这是pa持有)

这并不意味着无法回答这个问题。这只是意味着答案是出乎意料的,而且是一个讨厌的黑客。因此,假设问题不允许我们在main()中引入另一个变量,我们只需要更改pa以便调用func,并将其更改回来以便能够使用pa而不会产生令人讨厌的意外稍后在main()中。

pa++; func(&pa); pa--;

这个是OP问题的答案。目前发布的其他答案试图回答不同的,更简单的问题。但最初的问题更有趣,现在它有一个答案:-)但我觉得,比我更强调的是我用大写字母强调的观察。

为了恢复理智,我们需要重新审视func定义中的选择。

如果我们想要的只是访问存储在数组中的A,我们可以考虑完全消除对指针的依赖。

typedef struct { int x; int y;} A;
void bar(A a)
{
   printf("(%d,%d)\n", a.x, a.y);
}
void main() {
    A *pa;  
    pa = (A*) malloc(2 * sizeof(A));

    pa[0].x = 3;    pa[0].y = 4;
    pa[1].x = 13;    pa[1].y = 42;

    bar(pa[0]);      
    bar(pa[1]);
}

我们可能想要考虑让我们的函数采用A *参数而不是普通的A:有两个原因:1。如果函数需要修改指向的A和/或2.如果A碰巧是大型结构,我们不希望每次调用我们的函数都会导致将大块内存复制到堆栈中。

typedef struct { int x; int y;} A;
void foo(A *a)
{
   int tmp = a->x;
   a->x = a->y;
   a->y = tmp;
}
void bar(A a)
{
   printf("(%d,%d)\n", a.x, a.y);
}
void main() {
    A *pa;  
    pa = (A*) malloc(2 * sizeof(A));

    pa[0].x = 3;    pa[0].y = 4;
    pa[1].x = 13;    pa[1].y = 42;

    foo(&pa[0]); //or alternatively: foo(pa);
    bar(pa[0]);  //or alternatively: bar(*pa);

    foo(&pa[1]); //or alternatively: foo(pa + 1);
    bar(pa[1]);  //or alternatively: bar(*(pa+1));
}

可能有助于OP的另一个注意事项是,在执行指针运算时,指针的类型起作用。所以pa + 1的数值等于pa加上sizeof(A)的数值。 (这与尝试使func在下面的调用中使用pa的第二个元素失败有关:func(& pa + 1 * sizeof(A)))

OP的最后注释:如果你不想改变func的签名,因为你有计划在func中获得一个A **指针并用它做一些有趣的事情,比如给它分配另一个指针(例如指向一个指针)新malloc() - 分配了一大块内存),你会走进一个雷区!请检查我认为你会发现相关的另一个问题的答案:Why the free in line2 makes memcpy do nothing?? Is free before malloc is o.k??故事的寓意是指针是有用的但是概念复杂性和错误的可能性随着每个*呈指数级增长(并且通常有更好的选择) :-)

答案 3 :(得分:1)

试试这个:

func(&pa[0]); // for 1st object 
func(&pa[1]);// for 2nd object

pa将为您提供A数组的地址。 &pa将为您提供整个数组的地址。

表示,

A * ptr;

ptr = pa ;// increment `ptr` will give you next element in same array
ptr = &pa ;// increment `ptr` will give you the next array of that type

同时将函数func签名更改为

void func(A *pa)
{
     return;
}

=============================================== =============

如果要将指针数组传递给func

这样做:

A **pa = malloc(2*sizeof(A*));

然后像

一样发送
func(&pa[0]);
func(&pa[1]);

func将是

void func(A **pa)
{
     return;
}