首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C指针"type ** name“与"type * name[]”作为参数

C指针"type ** name“与"type * name[]”作为参数
EN

Stack Overflow用户
提问于 2013-09-06 17:12:33
回答 2查看 228关注 0票数 2

我有点困惑。下面是一个非常简单的例子:

代码语言:javascript
复制
#include <stdlib.h>

typedef struct 
{
  unsigned char one: 1;
  unsigned char two:1;
  unsigned char three: 1;
  unsigned char four: 1;
} nibble_bits;

typedef union
{
  unsigned char all : 4;
  nibble_bits bits;
} nibble;

void initArr(nibble ** arrLoc, unsigned int size)
{
  nibble * start = arrLoc[0];
  int i =0;
  for (i=0; i<size; i++)
    {
      start[i].all = 0;
    }
}

int main()
{
  nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));
  initArr(&fourNibbles,4);
}

这编译的很好,没有警告。但是,当我更改主要的第一行时:

代码语言:javascript
复制
nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));

至:

代码语言:javascript
复制
nibble fourNibbles[4];

我得到以下信息:

警告: main.c:在函数‘main’:main.c:150:警告:从不兼容的指针类型传递‘initArr’的参数1

在运行时,我得到一个“公共汽车错误10”。

在我看来,除了malloc为堆上的数组分配空间和在堆栈上分配数组声明外,行也在做同样的事情。但是(我想)无论哪种方式,"fourNibbles“都是”指向咬口的指针“,因此"fourNibbles”的地址将指向指向咬口的指针(nibble **)。

我在这里错过了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-06 17:24:16

这些根本就不一样。这

代码语言:javascript
复制
nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));

声明一个指针fourNibbles,而

代码语言:javascript
复制
nibble fourNibbles[4];

声明一个数组。数组和指针是两个完全不同的东西,(在对象级别)没有任何共同点。尝试在对象上下文(如&操作符)中交替使用它们只会导致灾难。在SO (搜索“数组指针差异”)以及这个事实上的标准C FAQ:http://c-faq.com/aryptr/index.html中,有很多关于这个主题的信息。

但是,还有一件事在代码中引起了注意。你的职能

代码语言:javascript
复制
void initArr(nibble ** arrLoc, unsigned int size)

是针对第一个变量专门定制的,因为它需要一个指向指针的指针作为它的第一个参数。如果您试图强制指向指向第一个参数的数组的指针(您已经有机会亲自观察该参数),它将无法工作。

然而,这里真正的问题是为什么您的initArr函数是以这样一种奇怪的方式编写的。这个序列

代码语言:javascript
复制
void initArr(nibble ** arrLoc, unsigned int size)
{
  ...
  nibble * start = arrLoc[0];
  ...
    start[i].all = 0;

看上去很不寻常。为什么要将指针传递给指针而不是普通的单层指针?你可以简单地做

代码语言:javascript
复制
void initArr(nibble *start, unsigned size)
{
  unsigned i;
  for (i = 0; i < size; ++i)
    start[i].all = 0;
}

这个版本将被称为

代码语言:javascript
复制
initArr(fourNibbles,4); /* note: no `&` operator */

它将与malloc-ed数组和显式声明数组兼容。

在C语言中,malloc的一个更好的成语是

代码语言:javascript
复制
nibble * fourNibbles = malloc(4 * sizeof *fourNibbles);

注意,在这个变体类型名称中,只提到过一次nibble

票数 3
EN

Stack Overflow用户

发布于 2013-09-06 17:19:02

您忽略了数组的地址与在表达式中使用时普通数组名称所使用的指针有不同的类型。

这就是:

代码语言:javascript
复制
int *a1 = ...;
int a2[] = { ... };

some_func(&a1);
some_func(&a2);

除非some_func()需要一个void *,否则不能正确。第一个调用传递一个int ** --一个指向int的指针;第二个调用传递一个int (*)[] --一个指向int数组的指针。从数组中删除&

然而,在您的代码中,问题更加复杂。因为函数需要一个nibble **,所以有问题。你应该做的是传递一个nibble *

代码语言:javascript
复制
void initArr(nibble *arrLoc, unsigned int size)
{
    for (unsigned int i = 0; i < size; i++)
        start[i].all = 0;
}

int main(void)
{
    nibble *fourNibbles_1 = (nibble *) malloc(4 * sizeof(nibble));
    nibble fourNibbles_2[4];
    initArr(fourNibbles_1, 4);
    initArr(fourNubbles_2, 4);
    initArr(&fourNubbles_2[0], 4);
}

您的实际代码正在做一些非常奇怪的事情。它所造成的破坏程度可能取决于指针与nibble相比有多大。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18663099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档