您的位置:首页 > 编程语言 > C语言/C++

C语言复习篇之数组与指针

2012-01-16 16:40 232 查看

C语言复习篇之数组与指针

学习了一段时间的嵌入式linux了,学习中有很多的东西需要总结,有经验有教训,我觉得把他写下来会更好,就当做是一种笔记的形式,记录学习中的点点滴滴,不仅仅自己可以经常复习,也可以提供来让别人共享的知识。这对自己来说其实是一种财富。不过说明一点,这只是笔记也许有些是摘至别处,有些是自己的想法,不保证每一句话都是自己说的。
今天的复习内容是数组与指针:
“嵌入式的学习中C语言是基础中的基础,是重中之重,也许许多人看到基础两个字就本能的反应:简单、不重要,恰恰相反,基础的东西才是最重要的东西,它决定了“上层建筑”是否牢固、可靠。”
好了废话不多说,复习开始了。
“指针是C语言的灵魂”这是所有学习C语言的大家所公认的一点。所以学好C,就必须玩转指针,因为C语言中最精华最奥妙最难搞清楚的莫过于指针了,特别是当指针和数组他们两个厮混在一起的时候,当然我觉得数组也可以理解为被束缚了的指针。
首先,理解概念:“指针”是指地址(俗称门牌号),是常量,通过指针的指示电脑可以找到需要的东西;“指针变量”是指存放地址的一个变量;“数组”是指存放具有相同属性的地址空间连续的的元素的集合。

指针使用注意项:

1.要理解指针,有四个点:指针的类型,指针指向的内容的类型,指针的值或
者叫指针所指向的内存区,指针本身所占用的内存区。
首先声明几个指针:(1)int*ptr; (2)char*ptr; (3)int**ptr; (4)int(*ptr)[3];
(5)int*(*ptr)[4];
指针类型:你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
这是指针本身所具有的类型。让我们看看例一中各个指针的类型:
(1)int*ptr;//指针的类型是int*
(2)char*ptr;//指针的类型是char*
(3)int**ptr;//指针的类型是int**
(4)int(*ptr)[3];//指针的类型是int(*)[3]
(5)int*(*ptr)[4];//指针的类型是int*(*)[4]
指针指向的类型:你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩
下的就是指针所指向的类型。
例如: (1)int*ptr;//指针所指向的类型是int
(2)char*ptr;//指针所指向的的类型是char
(3)int**ptr;//指针所指向的的类型是int*
(4)int(*ptr)[3];//指针所指向的的类型是int()[3]
(5)int*(*ptr)[4];//指针所指向的的类型是int*()[4]

指向任意类型的指针它本身的大小(sizeof (ptr))只占4个字节
数组使用注意项:

1.数组名是地址常量,不能改变本身的值,比如自加自减等操作。
2.遵循先定义后使用的原则。数组不能整体赋值,除非初始化的时候。
3.(C99新特性)变长数组VLA,是指用整形变量或表达式声明或定义的数组
,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是
固定的。
4.结构体柔性数组成员,即结构体的最后一个元素允许是未知大小的数组。
例:typedef struct A
{
int a;
double b;
char c[]; //必须是最后一位成员。
}test_t;
数组c不占用结构体A的空间(sizeof(A)=sizeof (int)+sizeof(double)),只是作为一个符号地址存在,,因此我们可以进行变长操作,如
下:
test_t *p=(test_t *)malloc(sizeof(test_t))+50*sizeof(char);
多分配出来的空间依然不占用结构体空间,仅提供给变长数组使用。
数组与指针的混合使用

一维数组int a[3];
a[0]
a[1]
a[2]
...
...
数组中内存地址是连续的。a为常量,代表数组首元素地址,a+1数组第二个元素的地址,&a数组首地址,&a+1数组外下一地址。

二维数组:int a[2][3]




a代表数组首元素地址,也代表第0行元素的首地址即&a[0],事实上当我们打印*a和*a[0]的值的时候,所得的结果都是一样的。当初想到这里我就有了一个疑问了:(?????)既然a和a[0]的值都是一样的,也就是说指向的地址是一样的,为什么a是表示a[0]而不是表示a[0][0]呢?

后来问过老师才知道,是因为虽然他们的值是一样的,但是他们所指向的内容的类型是不一样的,a的类型是int(*p)[3],而a[0]的类型是int p[3],所以a只能代表a[0]的地址而不是a[0][0]的地址。

说到这里就有一句重点的要提出来了:对于数组和指针的相互转换中,一定要抓住他们的类型比较,这样才能确保转换的正确性。下表列出数组和指针的等价关系:


一般我们认为任意维数的数组都可以看做是一个一维数组,实际上也是这样的,系统中并没有多维数组的概念,都是以一维数组来存储。

突然想起来,当初还有一个困惑我的问题:(????)书上写被赋值的指针变量前不能再加“* ”说明符,如int a;int *p;*p = &a;这是错误的表示方法,书上还写int a;int *p = &a;这是正确的,初看起来这好像很矛盾额,怎么也不理解。
其实是这样的:要弄清楚,首先要知道初始化和赋值的概念,比如int a = 5;这是初始化,而a = 5 这是赋值,还有一点,在指针中*p中的“*”代表解引用也就是“取内容”,因此*p所代表的是指针p所指向的内容。再回到问题,*p = &a 首先看看左右两边值得类型,左边是int型的值,右边是地址,类型根本不匹配,不能赋值;int *p = &a这是代表初始化,“*”的含义仅仅是代表变量是指针类型,而不是解引用,所以这样左右类型是匹配的可以赋值。

接下来是多级指针:

它是指一个指针的内容是另一个指针的地址,此指针就是多级指针。
int i = 100;int *pi = &i ;int **ppi = π

n级指针可以存放n-1级指针的地址:

int a;
Int *p = &a;
Int **pa = &p;
.....
.....
如此类推。
今天先复习到这里,明天继续......希望大家多多指点。

本文出自 “D.C_LOOK” 博客,请务必保留此出处http://doublewen.blog.51cto.com/3097132/764847
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: