设为首页 加入收藏

TOP

C语言数组与指针详解(二)
2014-11-24 00:40:10 来源: 作者: 【 】 浏览:71
Tags:语言 指针 详解
这一堆01被其类型限定了其代表的意义,类型为整形就是其值,指针地址类型,就是内存里的一个地址,字符型,就是其无符号整形代表的ASCII码。

3、字符串,是常量(字符指针指向一字符串,不是数组,数组和指针的区别在后面),其值不能再被改变,char * str = "abcdef";这行代码的意思是告诉编译器:老编啊,我这儿有个抽屉(指针变量str),你给我找个房间(存放字符串的内存空间),找到后,把钥匙给我放到这个抽屉里。老编去找客房经理,找到后问:有没有空房间啊,有的话给我一间,一哥们要开房,客房经理去查房间入住情况(内存管理),最后说,这儿有一间,它是老总的房间,你要不先用着,你用没事,你可别乱动里面的东西,你要是动的话,估计你那哥们就被KILL掉,老板是黑社会的,不过,你用没事。于是,老编将老总房间钥匙给我放到了抽屉(指针变量str)里,这样,我打开抽屉(指针变量),拿出房间(内存空间)钥匙(指针),去开房了,老编告诉的,别乱动,用没事(读取),一定不能破坏里面的结构(修改数据内容),要是乱动(修改数据),会出乱子的(段错误),然后你会被KILL的(异常结束程序)。如果有两个人,就会Double kill,老板就GOD LIKE了。

明白了常量和变量的区别后,再进行后面的学习就轻松点了!下面我们来看下指针的双胞胎哥们,数组。一般晕车人里面有很多也晕飞机,晕船,所以呢,晕指针的,也一般都会晕数组。

  • 数组:我们先咬文嚼字一下,数指数据,组,就是小组,由数据组成的小组,就叫数组(学计算机的,不光要学好计算机,也要学好语文,偶尔还要懂点医学,你要是经常看计算机图书,你看台湾人写的书,都有很多文言文在里面,我们这点做的完全没有台胞做的好,所以人家计算机牛啊,世界上的电子代工,台湾占了绝大数比例)。

数组有几个特点一定要注意,看到数组就要想到:

1、 数组里面的数据类型是相同的,小组里面的成员肯定要一样的啊,驴堆里站一马,驴马不分,鸡窝里蹲一丹顶鹤,鹤立鸡群,这都是不合群的东西,计算机里面也讲“和谐”。我们顺便看下数据的基本类型:int float double char 这些是基本类型,所以它们可以存在以下类似数组:int a[10], float f[10], doule d[10], char str[10]; 它们每一个都有10个元素,每一个元素的类型都是其前面声明的类型。我们是学嵌入式的,我们不能光看到表面的东西,我们要看到底,好东西是走了光才叫好,光有好东西,别人不知道也不行。其实数组在内存中是连续分配的,如下图:

\

定义了一char型数组a,它有6个元素,分别是'A', 'B', 'C', 'D', 'E', 'F',它们在内存里面是连续存放的,每个元素占用一个字节。 强烈谴责那些将'A' 当成"A"的人,前者是单个字符,后者是字符串,鄙视那些,问“字符和字符串有什么区别?”的人,不知道字符和字符串的区别,那你吃过羊肉串吗?单个羊肉块能叫串吗,多个羊肉块串起来才叫串,所以字符是单个,字符串可以是多个字符组成的数组(最后有一个结束符号\0),羊肉块串起来一烤就叫烤羊肉串,字符串一拷,叫拷贝串,学计算机哪有那么简单,要是我开个学校,入学前要体检,测视力,量身高体重,....,三围什么的,不行的PASS。

仔细看上面的图,每一个字符都有一个地址,它们的跨度是1(字节),数组的每个元素都可以通过下标来访问,下标(index, for循环变量经常用i就是因为这个东西)其实就是他在数组中的位置,也就是他的号,拉10个人过来,报数,1,2,3.....,只不过,C语言里数组的下标是从0开始的,在计算机里面能访问的最小单位就是字节了,也就是地址只能找到以字节为单位,不能再精确了。数组名a和变量名道理上是一样的,在编译时就和数组的首地址绑定上了,a就是数组的首地址,变量名和数组名其实都是方便人们记忆而取的代号,它在代码反汇编后,其实不存在变量名的,回想下,访问数据有两种方式,既然反汇编后的代码不存在变量名,只能通过那种方式访问数据了,那就是地址。数组中的每一个元素,可以被看成一个变量(回想下变量的特点),因此其可以被读,写,修改,爱怎么得瑟怎么得瑟,你只要不把房间拆了(内存空间),怎么折腾都行。每一个元素的地址都可以通过首地址的偏移量(offset这个词记住,四级里没有)来算出来,这个偏移量说白了就是下标了。比如上面的图中:'C'所在地址0x28c5,相对首地址0x28c3的偏移量是2,那a[2]也可以访问'C'了,注意一点,a代表数组代表数组的首地址代表数组第一个元素的地址,这“三个代表”一定要记住。那a+1呢,a是三个代表,那它是第一代表还是第二个代表,还是第三个代表呢?这儿的a应该是第一个元素地址的意思表示的意思应该是&a[0],a+1是个地址的算术运算,而数组是个一维数组,数组中每个元素都是一个字符,a+1就是a当前地址0x28c3的下一个元素的地址0x28c4(结合图来看),也就是'B'的地址,如果a是一个二维数组名的话,那么二维数组被编译器理解为一个一维数组,一维数组里的每一个元素是一个一维数组,有点乱,别慌,屡一下,看下图:

\

a是个二维数组,它有3X4=12个字符元素,而编译器将它认为是一个一维数组,它有三个元素,分别是a[0], a[1], a[2], 每一个元素是一个含有4个字符的数组,那么a+1的话,是&a[0]的地址,a[0]是一个一给数组,取了一个数组的地址,再加1 ,肯定就是下一个数组的地址了,就是a[1]上图,那么这个时候它的地址增加可不再是1了,而是列数4,也就是说是a这个二维数组中元素(一维数组)的长度。

www.2cto.com 回到前面那个图:a[5] - a[3] = 地址的运算,这里算的也是元素的相对偏移量,结果当然是2,虽然0x28c8- 0x28c6 = 2结果也是2,不过意义不一样,如果数组类型换成int a[10], 那么a[5] - a[3] 还是2,不是8,这个直接用下标相减就对了。

因此我们可以总结一下,指针相加减时,要看类型,打狗看主人,指针加减看类型,其运算的值n*sizeof(类型),比如:字符型地址加1 ,其实地址加也是sizeof(char) = 1,整形地址加1,地址加sizeof(int) = 4,结构体数组中,地址加1,地址加sizeof(结构体)。

通过上面的分析可以看出,数组有很多地方很相似,其实,编译器这哥们处理数组的时候就是将其看成指针来处理的,没有办法,编译器只认地址,变量名一直都是被编译器藐视的。

看一个程序图:

\

程序图这个名词是我自创的,有版权的,因为好多东西说不清,道不明,一个图全搞定。

上面的执行结果是什么?已经很清楚了。休息会。

上面的例子结果是:B和E


摘自 mr_raptor的专栏

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言关键字 - 专一王子:Volatile 下一篇OpenGL开发教程之--Windows下环境..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: