C / C ++中的指针/数组语法(char ** p,* p [n])

时间:2010-02-21 07:57:12

标签: c pointers

对于指针,我对使用char **或char *或* array [n]等的声明和函数参数感到困惑。就像一个函数采用(* array [n])参数一样,我把它传给**型吗?

我尝试使用右 - 左规则并知道p将是指向char(char ** p)的指针,而p是n个指针的数组(* p [n]),但有人说* p [n]和** p基本上是等价的。这是真的吗?

3 个答案:

答案 0 :(得分:8)

在正确的上下文中(即函数的参数),以下声明是等效的:

int main(int argc, char *argv[]);
int main(int argc, char **argv);
int main(int argc, char *argv[12]);  // Very aconventional!

类似的注释适用于函数定义(括号中用大括号代替分号)。

在任何其他情况下,符号之间存在重要差异。例如:

extern char *list1[];
extern char **list2;
extern char *list3[12];

第一个说某个地方有一个包含'char *'值的不确定大小的数组。第二个说某处 - 可能在这里 - 有一个值包含指向char指针的指针。第三个说某个地方 - 可能在这里 - 有一个由12个字符指针组成的数组。

但是,所有三个列表都可以以相同的方式引用 - 假设它们实际上已经被定义和初始化。

list1[0][0] = '1';
list2[0][0] = '2';
list3[0][0] = '3';

此外,如果将它们传递给这样的函数:

function(list1, list2, list3);

然后该函数可以声明为:

void function(char **list1, char **list2, char **list3);

数组(list1,list3)从数组衰减到指向数组第一个元素的指针;当然,list2已经是指向指针的指针。

在以下函数中需要注意的一个细节:

void otherfunction(char *list[12])
{
    ...
}

C编译器不会将该声明与以下内容区分开来:

void otherfunction(char **list)
{
    ...
}

void otherfunction(char *list[])
{
    ...
}

特别是,它没有数组边界检查,就函数而言,12也可能不存在。


C99引入了VLA(可变长度数组)类型,并在数组边界中引入了带有“static”和大小的符号。您需要阅读标准才能完全理解这些标准。

在下面的函数中可以说数组的大小很重要,并且在运行时确定。通常使用二维数组,除了第一个之外的所有维度都需要指定。

void vla_function(size_t m, int vla[m][m]);

引用标准(第6.7.5.3节):

void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);
  

(注意,最后一个声明还指定对f的任何调用中对应的参数必须是a   非空指针,指向至少三个5个双精度数组中的第一个,其他数组则没有。)

答案 1 :(得分:5)

读取C声明符(这是带有*和[]的变量的一部分)相当细微。有一些网站提示:

char**是指向(可能是多个)char(可能是多个)指针的指针。例如,它可能是指向字符串指针的指针,也可能是指向字符串指针数组的指针。

char*[]是指向char的指针数组。当你有一个以此为参数的函数时,C编译器会将其“衰减”为char**。这只发生在第一层......所以,举一个复杂的例子,char*[4][]变为char*(*)[4]。阅读上面的链接,这样你就可以理解这意味着什么。

或者你可以做一个(非常明智的)并制作一堆typedef。我不这样做,但在你擅长阅读宣传员之前,这是一个好主意。

typedef char * stringp;
void func(stringp array[]) { ... }
static stringp FOUR_STRINGS[4] = { ... };

答案 2 :(得分:0)

如果n==0,则他们引用相同的内存。数组索引基本上是指针加上偏移量。 *(p[n])**(p+n)相同。你可以亲自看看它在C中有多简单,因为array[4]4[array]会给你同样的东西。