C编程:数组和指针



可能重复:
数组名称是C中的指针吗?

如果我定义:

int tab[4];

选项卡是一个指针,因为如果我显示选项卡:

printf("%d", tab);

上面的代码将显示内存中第一个元素的地址。

这就是为什么我想知道为什么我们不定义如下的数组:

int *tab[4];

因为tab是一个指针。

谢谢你的帮助!

选项卡是一个指针

否,tab是一个数组。具体为int[4]。但是,当您将其作为参数传递给函数时(以及在许多其他上下文中),数组将转换为指向其第一个元素的指针。您可以看到数组和指针之间的区别,例如,当您调用sizeof arraysizeof pointer时,当您尝试分配给一个数组(不会编译)时,等等。

int *tab[4];

声明了指向CCD_ 5的四个指针的数组。我看不出这与数组和指针之间的混淆有什么关系。

tab不是指针,它是一个由4个整数组成的数组,当传递给函数时,它衰减为指向第一个元素的指针:

int tab[4];

这是另一个数组,但它包含4个整数指针:

int *tab[4];

最后,为了完整起见,这是一个指向4个整数数组的指针,如果你取消引用它,你会得到一个4个整数的数组:

int (*tab)[4];

你没有完全错,这意味着你的陈述是错误的,但你离真相并不远。

C下的数组和指针共享相同的算术,但主要区别在于数组是容器,指针就像任何其他原子变量一样,它们的目的是存储内存地址并提供有关指向值类型的信息。

我建议读一些关于pointer arithmetic的东西

  • 指针算术
  • http://www.learncpp.com/cpp-tutorial/68-pointers-arrays-and-pointer-arithmetic/

考虑到Steve Jessop的评论,我想添加一个片段,向您介绍指针算术的简单有效的世界:

#include <stdio.h>
int main()
{
int arr[10] = {10,11,12,13,14,15,16,17,18,19};
int pos = 3;
printf("Arithmetic part 1 %dn",arr[pos]);
printf("Arithmetic part 2 %dn",pos[arr]);
return(0);
}

数组的行为可以像指针,甚至在您的情况下看起来像指针,您可以通过它们不是指针来应用相同的算术。

int *tab[4];

这个定义意味着tab数组包含pointers of int而不是int

来自C标准

编码指南

数组对象到指针指向它们的第一个元素会给尝试在C.中为数组制定更强的类型检查。没有经验,在在C语言中,开发人员有时会将数组和指针等同起来比本要求(适用于使用在表达式中,而不是在声明中)。例如,在:

file_1.c

extern int *a;

file_2.c

extern int a[10];

a的两个声明有时被错误地假定为开发人员的兼容性。很难看出什么是指导方针建议将克服开发人员不正确的假设(或较差培训)。如果指南建议指定了一点如果遵循声明,这个问题将不会被419.1识别在一个文件中声明。与功能指示符的使用不同,开发人员熟悉这样一个事实:具有数组的对象转换为typetype的函数指示符隐式转换为指向其第一个元素的指针。无论是应用一元&操作人员对于具有数组类型的操作数,读者可以视觉提示或使他们怀疑作者的意图("那个多余的操作员在那里干什么?")尚不清楚。

示例

static double a[5];
void f(double b[5])
{
double (*p)[5] = &a;
double **q = &b; /* This looks suspicious, */
p = &b; /* and so does this. */
q = &a;
}

如果数组对象具有寄存器存储类,则行为为未定义的

在大多数情况下,数组类型的表达式将被转换("decay")为指针类型的表达式,表达式的值将是数组中第一个元素的地址。此规则的例外情况是,数组表达式是sizeof_Alignof或一元&运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字。

int tab[4];

如果CCD_ 15,则将CCD_。在报表中

printf("%d", tab); // which *should* be printf("%p", (void*) tab);

表达式tab从类型"int的4元素数组"转换为"指向int的指针"。

最新更新