Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41044
  • 博文数量: 7
  • 博客积分: 76
  • 博客等级: 民兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-29 20:03
文章分类

全部博文(7)

文章存档

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);

这里不需要使用&运算符,而使用数组名称,就像指针一样。如果以这种方式使用数组名称,而没有带索引值,它是引用了数组的第一个元素的地址。

这里要注意,数组不是指针,它们有一个重要的区别:可以改变指针包含的地址,不能改变数组名称引用的地址。

用一个例子来说明一下:

#include 
int 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

二、多维数据与指针

前面说的是一维数组,下面来说一下,多维数组与指针间的关系。指针与二维、多维数组名称之间的差异更为明显。

下面用一个例子来说明

#include 
int 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.

如下图所示:



以上是说了多维数组,下面来说一下,多维数组和指针间的应用

还是用一个例子来说明,修改上一个例子:

#include 
int 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数组的方法

好了,指针与数组就先写到这里,这些都是一些理论上的东西,重要的还是得多练习才行。

阅读(1563) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~