2013年(7)
分类: C/C++
2013-01-22 15:00:57
一、数组和指针
数组:是相同类型的对象集合,可以用一个名称引用。
指针:是一个变量,它的值是给定类型的另一个变量或常量的地址。使用指针可以在不同的时间访问不同的变量,只要它们的类型相同即可。
数组和指针似乎完全不同,但它们有非常密切的关系,有时还可以互换。以字符串为例,字符串是char类型的数组。如果用scanf()输入一个字符,可以使用如下:
char single;
scanf("%c", &single);
这里,scanf()需要寻址运算符,因为scanf()需要存储输入数据的地址。如果是数组,应该如下:
char multiple[10];
scanf("%s", multiple);
这里不需要使用&运算符,而使用数组名称,就像指针一样。如果以这种方式使用数组名称,而没有带索引值,它是引用了数组的第一个元素的地址。
这里要注意,数组不是指针,它们有一个重要的区别:可以改变指针包含的地址,不能改变数组名称引用的地址。
用一个例子来说明一下:
#includeint main(void) { char multiple[] = "My string"; char *p = multiple[0]; printf("\\nThe address of the first array element: %p", p); p = multiple; printf("\\nThe address obtained from the array name: %p\\n", p); return 0; }
在计算机上输出:
The address of the first array element: 0x0013ff62
The address obtained from the array name: 0x0013ff62
二、多维数据与指针
前面说的是一维数组,下面来说一下,多维数组与指针间的关系。指针与二维、多维数组名称之间的差异更为明显。
下面用一个例子来说明
#includeint main(void) { int i; char board[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} }; for(i = 0; i < 9; i++) printf("board: %c\\n", *(*board + i)); return 0; }
程序输出结果如下:
board: 1
board: 2
board: 3
board: 4
board: 5
board: 6
board: 7
board: 8
board: 9
这个程序中主要看:
printf(" board: %c\n", *(*board + i));
可以看到,使用表达式*(*board + i)可以得一个数组元素的值。括号中的表达 式*board + i会得到数组中偏移量为i的元素的地址,然后再取消对它的引用,会得到这个地址中的值。在这里括号的作用很重要的,省略它们会得到board所指向的值(即存储在board中的地址引用的值)再加上i的值。
以上总结:board 对应的是board数组第一个元素的地址,然后对board取消运算等到*board 对应的是board数组第一个元素的地址即board[0][0]的地址。然后再对*board取消运算得到**board则对应的是数组board第一个元素的值,在上面的例子中是1.
如下图所示:
以上是说了多维数组,下面来说一下,多维数组和指针间的应用
还是用一个例子来说明,修改上一个例子:
#includeint main(void) { int i; char board[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} }; char *pboard = *board; ///board[0][0]的地址存储到pboard中 for(i = 0; i < 9; i++) printf("board: %c\\n", *(pboard + i)); return 0; }
输出结果和上面的例子一样。
这里用数组中的第一个元素的地址初始化指针,然后用一般的指针算术运算整个数组:
char *pboard = *board;
for(i = 0; i < 9 ; i++)
printf(" board: %c\n", *(pboard + i));
这里还要注意,取消了对board的引用(*board),得到了需要的地址,因为board是数组board[0]的地址,而不是一个元素的地址。可以用以下的方式初始化指针pboard:
char *pboard = &board[0][0];
效果是相同。用下面的语句初始化指针pboard:
pboard = board;
这是错误的。因为pboard和board有不同的间接级别。这个专业术语的意思是pboard指针引用的地址包含一个char类型的值,而board引用一个地址,那个地址引用另一个char类型的值的地址。board比pboard多了一级。因此pboard指针需要一个*,以获得地址的值,而board需要两个*。
访问数组元素
可以使用几种方法访问二维数组的元素。下面图片列出了访问board数组的方法
好了,指针与数组就先写到这里,这些都是一些理论上的东西,重要的还是得多练习才行。