数组的名字是C语言中的指针吗? 如果不是,数组的名称和指针变量之间的区别是什么?
当前回答
数组名本身会产生一个内存位置,所以你可以像对待指针一样对待数组名:
int a[7];
a[0] = 1976;
a[1] = 1984;
printf("memory location of a: %p", a);
printf("value at memory location %p is %d", a, *a);
你还可以对指针做其他漂亮的事情(例如增加/减去偏移量),你也可以对数组做:
printf("value at memory location %p is %d", a + 1, *(a + 1));
在语言方面,如果C语言没有将数组公开为某种“指针”(学究地说,它只是一个内存位置)。它不能指向内存中的任意位置,也不能由程序员控制)。我们总是需要这样编码:
printf("value at memory location %p is %d", &a[1], a[1]);
其他回答
像这样声明的数组
int a[10];
为10个int类型分配内存。你不能修改a,但你可以用a做指针算术。
这样的指针仅为指针p分配内存:
int *p;
它不分配任何int型。你可以修改它:
p = a;
并像使用a一样使用数组下标:
p[2] = 5;
a[2] = 5; // same
*(p+2) = 5; // same effect
*(a+2) = 5; // same effect
数组是数组,指针是指针,但在大多数情况下,数组名被转换为指针。经常使用的一个术语是它们衰减为指针。
这是一个数组:
int a[7];
A包含7个整数的空格,你可以在其中一个整数中赋值,就像这样:
a[3] = 9;
这里有一个指针:
int *p;
P不包含任何整数的空格,但它可以指向整数的空格。例如,我们可以将它设置为指向数组a中的一个位置,例如第一个:
p = &a[0];
让人困惑的是,你也可以这样写:
p = a;
这不会将数组a的内容复制到指针p(不管这意味着什么)。相反,数组名a被转换为指向其第一个元素的指针。这个分配和之前的一样。
现在你可以像使用数组一样使用p:
p[3] = 17;
这样做的原因是C语言中的数组解引用操作符[]是用指针定义的。X [y]的意思是:从指针X开始,在指针指向的地方向前移动y个元素,然后取那里的任何元素。使用指针算术语法,x[y]也可以写成*(x+y)。
为了使它适用于普通数组,例如我们的a,[3]中的名称a必须首先转换为一个指针(指向a中的第一个元素)。然后我们向前推进3个元素,并取其中的任何元素。换句话说:取数组中位置为3的元素。(它是数组中的第四个元素,因为第一个元素编号为0。)
因此,总的来说,C程序中的数组名(在大多数情况下)被转换为指针。一个例外是在数组上使用sizeof操作符。如果在这种情况下a被转换为指针,sizeof a将给出指针的大小,而不是实际数组的大小,这将是相当无用的,所以在这种情况下a意味着数组本身。
数组名的行为类似于指针,指向数组的第一个元素。例子:
int a[]={1,2,3};
printf("%p\n",a); //result is similar to 0x7fff6fe40bc0
printf("%p\n",&a[0]); //result is similar to 0x7fff6fe40bc0
这两个print语句将为一台机器提供完全相同的输出。在我的系统中,它给出:
0x7fff6fe40bc0
下面的示例提供了数组名和指针之间的具体区别。假设你想用给定的最大维数表示一条一维线,你可以用数组或指针来实现:
typedef struct {
int length;
int line_as_array[1000];
int* line_as_pointer;
} Line;
现在让我们看看下面代码的行为:
void do_something_with_line(Line line) {
line.line_as_pointer[0] = 0;
line.line_as_array[0] = 0;
}
void main() {
Line my_line;
my_line.length = 20;
my_line.line_as_pointer = (int*) calloc(my_line.length, sizeof(int));
my_line.line_as_pointer[0] = 10;
my_line.line_as_array[0] = 10;
do_something_with_line(my_line);
printf("%d %d\n", my_line.line_as_pointer[0], my_line.line_as_array[0]);
};
这段代码将输出:
0 10
这是因为在do_something_with_line函数调用中,对象被复制,因此:
指针line_as_pointer仍然包含它所指向的相同地址 数组line_as_array被复制到一个没有超出函数作用域的新地址
因此,当你直接将数组输入到函数时,数组不是由值给出的,当你将它们封装在结构中时,它们是由值给出的(即复制),这概述了与使用指针实现相比,在行为上的主要区别。
数组名本身会产生一个内存位置,所以你可以像对待指针一样对待数组名:
int a[7];
a[0] = 1976;
a[1] = 1984;
printf("memory location of a: %p", a);
printf("value at memory location %p is %d", a, *a);
你还可以对指针做其他漂亮的事情(例如增加/减去偏移量),你也可以对数组做:
printf("value at memory location %p is %d", a + 1, *(a + 1));
在语言方面,如果C语言没有将数组公开为某种“指针”(学究地说,它只是一个内存位置)。它不能指向内存中的任意位置,也不能由程序员控制)。我们总是需要这样编码:
printf("value at memory location %p is %d", &a[1], a[1]);