C语言学习之 数组,指针,字符串. (二)

原创
2012/11/04 16:48
阅读数 121

前篇内容介绍了简单的 数组与指针 的简单形式. 都是简单的 *p 或者 a[5] 这样的简单形式. 顺便引出了 typedef .
内容相当简单没有深度.  概念也相当简单. 一切皆为数字, 计算机操作的都是数字.

如果上篇没有疑问,下面这段不用再读, 直接跳到 typedef的应用.

回顾一下概念.  变量是什么. 只是一种表示形式而已, 用以表示恰当的存储空间大小的形式.  
类型, 只是一种概念,也用来表示空间的大小.  与变量的关系.  变量是表示形式, 类型是空间的大小.
变量都有类型,  指针又是什么. 指针也是一种变量,也有存储空间, 空间的大小就是指针类型所占用的大小. 指针名就是用来表示用以存储"空间地址"的存储空间. 所有指针占用的空间在同一平台下是相等的. 可以用 sizeof(void *) 来获取.
基本的类型有 char, 占用8位, 1字节.  short , 占用16位, 2字节, sizeof(char) =1, sizeof(short) =2 . 还有其他一些类型. 

typedef 可以用来定义一些类型.  最简单的形式就是给一些基本类型起一些其他的名字. 比如 typedef int abc; 之后, abc 类型和int 类型就是一样的.

数组是一段连续存储空间的表示形式. 比如 char a[5]; 这条语句是一个声明.    表示 5 个sizeof(char) 的连续存储空间. 数组名是 a ,  其实, a 也是一个数字,  这个数字就是 所表示的5个空间的首地址. 占用空间大小计算方式为 5*(sizeof(char)); 同理 short b[5]; 中的 b也是一个数字, 对应的是 5个连续 short  的空间首地址.  short b[5]占用的存储空间大小为 5*(sizeof(short));

指针 也是占用存储空间的, 占用大小也是固定的.  指针也是一个数字. 存储的是一个 存储空间地址.

typedef的应用

这些在上篇都讲过,这里又啰嗦了一遍. 上篇还讲了一个小魔法. 指针与数组. 下面给出的还是上篇中的例子,我们做些小修改.


#include <stdio.h>

typedef char ta[5];

int main(int argc, char *argv[]) {

	ta a[3]; /*声明数组*/
	int i,j;
	for(i = 0; i < 3; i++) {
		for (j=0; j < 5;j++ ) {
			a[i][j] = i*10+j;
		}
	}

	ta *pa; pa=&a[0]; /*这样好理解. 指向数组首地址*/
	printf("%d\n", *pa);
	printf("%d\n", a);
	printf("%d\n", pa[1][3]);
	printf("%d\n", *(pa[1]+3));
	printf("%d\n", *(*(pa+1)+3));

	printf("%d\n", a[0][0]);
	printf("%d\n", *(*(pa+0)+0));
	printf("%d\n", **pa);

	a[0][0] = 99;
	printf("%d\n", **pa);
}

其中 a 是一个数组, 表示一段连续存储空间. a也是一个数字, 计算机中一切都是数字, a也表示连续存储空间的首地址.
 接下来看看 a 这个数组的访问. a 有3个元素, 分别是 a[0] a[1] a[2]. 计算机中,一切都是数字.  a 又是 元素的首, 还有其他访问呢形式可用. 
 a[0] 可表示为  *(a+0) . 意思是, 取 a+0 这个地址对应的内容.  由于 a+0 等于a , 可简单写成 a,  所以 *(a+0) 可简单写成*a;
a[1] 又可表示 *(a+1). 同理 a[2] 可以用 *(a+2) .
这里需要记住的一点, 一切都是数字, 数组表示形式,只是为了让我们好用,好理解, 任何数组都可以用指针的表示形式来表示.

请留意 最后两条语句.  看结果是不是跟想象中的一样.  在这里出现了 **pa ; 试着理解它. 再试着理解*(*pa+1) 和 (*pa)[1] 的关系.  他们是一样的. 用指针表示形式都是一样的.
这里需呀记住的只有一点. 透过表象看本质. 多维数组, 没那么神秘,  数组是用来表示一段连续的存储空间. 多维数组是对多个一维数组的抽象. 最终的本质都是通过指针来访问目标的. 在这里只需要注意的是, 每个目标究竟表示的是什么.
比如 a[1] , 表示的是 是个 ta 类型的内容. ta 类型又表示为一个长度为5的char 数组. 如果将 char 换成 short 类型,结果不会有任何改变. **pa 就是用来表示 *(*pa+0), *pa 的类型是ta, ta又是一个数组, 所以又可以表示为 (*pa)[0],又可以表示为(*(pa+0))[0],或者(pa[0])[0]; 也就是pa[0][0];
二维数组就是这么回事. 用同样的思路去理解3维数组就可以了. 数组,也没什么大不了. 

char x[3][5] ,这个声明应该怎么去理解呢? 可以假想成 , 有一个类型, 他的样子类似于 char y[5]; 
char x[3][5]; 就是有3个像 char y[5] 这样的东西存在. 当然, 的确没有 char y[5]这样的东西. 因为 没有 char y[5] 这样的类型.
 所以 char x[3][5] 应该理解成  x[3*5] 也就是 char x[15];
可以将 所有的 char 类型 改变成 short 类型加深理解.

数组可以转换为指针, 指针的形式表示. 反之却不一定成立. 

数组与指针就这点关系. 认清本质 会 发现, 也不过如此.
下面将是 字符串与数组的关系.很简单. C语言里没有字符串这个类型, 字符串用 字符数组的概念表示. 不同的是,每个字符串后面都有 '\0' 结束.  字符串的本质就是一个字符数组. 然而,我们运用字符串的时候.更多操作的都是指针. 一个指向字符数组的指针. char (*a)[n]; 类似于这样的指针. 当然, char (*a) [n] 中的 n 是字符串长度下标. 声明的时候可以直接声明成一个字符指针就可以使用了.  留给下一篇再讲.

展开阅读全文
打赏
1
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
1
分享
返回顶部
顶部