1.数组变量
当定义并初始化了一个数组后,数组变量名的本质是一个指针,它代表数组中第一个变量a[0]的地址。当你想要看数组的地址时,不需要使用取地址符。
#include <stdio.h>
int main()
{
int a[] = {1,2,3,4,5};
printf("%p\n",a);
printf("%p\n",&a[0]);
return 0;
}
输出:
000000000062FE00
000000000062FE00
而且,一个数组不能通过赋值符号接收另一个数组的所有值,因为数组的指针是const型。即在遍历数组时,不能直接把一个数组赋值给另外一个数组。即下面操作是错误的。
int a[] = {1,2,3};
int b[] = a;
2.传入函数的数组是神马?
函数参数中的数组实际上是一个指针,一个原数组起始元素a[0]的指针。
#include <stdio.h>
void see(int a[]);
int main()
{
int a[] = {1,2,3,4,5};
printf("%p\n",&a[0]);
see(a);
return 0;
}
void see(int a[])
{
printf("%p\n",a);
printf("%d\n",sizeof(a));
printf("%d",sizeof(int*));
}
输出:
000000000062FE00
000000000062FE00
8
8
- sizeof(a) == sizeof(int*);
- 但可以用数组的运算符[]进行运算;
3.数组变量是个特殊的指针。
(1)开头就讲了,数组变量本身表达地址,所以下面的做法是正确的:
int a[10];
in* p = a;//无需用&取地址
但是,数组的单元表达的是变量,需要用&取地址符,这点在最开始的代码中验证过了。所以
a == &a[0]
(2)[]运算符可以对数组做,也可以对指针做:
p[0]<==>a[0]
(3)*运算符可以对指针做,也可以对数组做
- *a == a[0]
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
printf("%d\n",*a);
*a = 10;
printf("%d\n",*a);
if(*a==a[0])
{
printf("yes");
}
return 0;
}
输出:
1
10
yes
(3)数组变量是const的指针,所以不能被赋值
- int a[] <==> int *const a
做一个错误示范:
int a[] = {1,2,3};
int b[] = a;
4.数组作为函数参数时
前面说了,传入函数的并不是数组,而是a[0]的地址指针。所以当数组作为参数传入函数时,在函数里:
- 不能再利用sizeof来计算数组的元素个数。
- 往往必须再用另一个参数来传入数组的大小。
#include <stdio.h>
void see(int a[],int len);
int main()
{
int a[] = {1,2,3,4,5};
int len = sizeof(a)/sizeof(a[0]);
see(a,len);
return 0;
}
void see(int a[],int len)
{
printf("%d",len);
}
输出:
5
在函数声明时的参数表中,下面四种函数原型是等价的:
int sum(int *a,int n);
int sum(int *,int);
int sum(int a[],int n);
int sum(int [] ,int);
[]为数组标识,它只能用到指针的后面,前面 我们已经讲过数组变量a就是个指针,所以它可以用a[n];一个指针p也是可以用的p[n]。
*后面必须是指针变量。如果一个变量声明时在前面使用 * 号,表明这是个指针型变量。换句话说,该变量存储一个地址,而 *(此处特指单目运算符 * ,C语言中另有 双目运算符 *) 则是取内容操作符,意思是取这个内存地址里存储的内容。