最近在学习数据结构中的矩阵压缩存储的时候涉及到了许多有关数组的操作。在使用数组的时候更是对数组这个东西不知所云,以下是我对其的一下理解。
首先第一个问题:数组是一种类型吗?
想来回答这个问题就必须来从编译原理的角度来说类型是什么,类型是某一类的值的集合,如整型(int,long,short),字符型(char),浮点型(float,double)。从这个角度来说,数组是一种类型它是一种“复合类型”——应用类型构造器作用在基本类型上所形成。
第二个问题 这种类型有什么特殊的地方呢?
我们知道 int a=3;这个语句的意义是定义一个变量a然后我们在作用范围内可以使用a来进行运算eg:a++;编译器又是怎么知道符号a代表的是整型数字3呢?这是符号表的功劳。我们在构造一个变量a的时候是取一个地址将其命名为a,然后再编译的时候就把a的相关信息存储到符号表中,然后在进行a++的操作的时候就根据符号表来找到a的相关信息来进行操作。
那么int a[3] = {1,2,3};的时候呢?很明显a并不是某一个地址的名字也就是说它就只是一个符号,实际并不存在。也就是说它在符号表中的地址一栏不好填写了。所以就干脆直接把首地址填写在地址栏(因为我们想要用这种类型,所以就必须把它设计遇到的问题解决)。但是&a和a的值是一样的但是类型却不同,如果不是很明白那么我给你俩个例子理解(这俩个例子是从别人博客中搬来的因为我觉得举的特别好):
帮助理解数组类型的特殊性:
1。编译器对数组名和指针变量的处理方式
编译器在编译时会产生一个符号表,记录了符号名和它的地址。对于指针变量,这显然很好理解。而数组名就不那么明显了,它仅仅是一个符号而已,何来地址?编译器是这样处理的,它记录了array[0]的地址;这和我们通常的理解也是一样的。
2。带下标形式的数组和指针寻址方式
(1)数组情形
char a[9]="abcdefgh";
...
c=a[i];
在编译期,会在符号表中创建这样一条记录:
name:a address:9980
要获取a[i]的值分两个步骤:
step 1:取得i的值并和9980相加
step 2:在内存地址(9980+i)处取其内容
(2)指针情形
char* p="abcdefgh";
...
c=p[i];
在编译期,会在符号表中创建这样一条记录:
name:p address:4624
要获取p[i]的值分三个步骤:
step 1:在内存地址4624处取其内容,比如说“5081”
step 2:取得i的值并和5081相加
step 3:在内存地址(5081+i)取其内容
帮助理解a和&a值一样但是类型不同:
#include <stdio.h>
int a[2] = {1,2};
int main(){
printf("a = %p\n", a); // I
printf("&a = %p\n", &a); // II
printf("a + 1 = %p\n", a + 1);// III
printf("&a + 1 = %p\n", &a + 1);// IV
return 0;
}
总结一下:数组是一种特殊的类型,数组的"地址"是首地址,他的值也是首地址。虽然值相同但是类型是不同的。比如 int a[3] = {1,2,3} ,sizeof(a)是12,因为a是一个数组。sizeof(&a)是4因为&a是一个数组指针也是指针变量所以是4。
说到这里那么基本也就说清楚了吧!参考链接:http://blog.chinaunix.net/uid-10221131-id-350168.html
http://www.cnblogs.com/hdu-2010/p/3557784.html