文档章节

C Primer Plus 第10章 数组和指针 10.3 指针和数组

idreamo
 idreamo
发布于 2016/07/25 06:36
字数 1193
阅读 33
收藏 0

我们举一个这种变相使用的例子:数组名同时也是该数组首元素的地址。也就是说,如果flizny是一个数组,下面的式子是正确的:

flizny == &flizny[0]  //数组名是该数组首元素的地址

flizny和&flizny[0]都代表首元素的地址。两者都是常量,因为在程序运行过程中它们保持不变。然而可以把它们作为赋给指针变量的值,然后您可以修改指针变量的值。如程序清单10.8所示,请注意给指针加上一个数的时候,它的值会发生什么变化?(指针说明符%p通常以十六进制形式显示值)。

程序清单10.8  pnt_add.c程序

//pnt_add.c -- 指针加法
#include <stdio.h>
#define SIZE 4
int main(void)
{
    short dates[SIZE];
    short *pti;
    short index;
    double bills[SIZE];
    double *ptf;

    pti = dates;  //把数组地址赋给指针
    ptf = bills;

    printf("%23s %10s\n","short","double");
    for (index=0;index<SIZE;index++)
        printf("pointers + %d:%10p %10p\n",index,pti+index,ptf+index);
    return 0;
}

输出结果如下:

                  short      double 
pointers + 0:0x0064fd20  0x0064fd28
pointers + 1:0x0064fd22  0x0064fd30
pointers + 2:0x0064fd24  0x0064fd38
pointers + 3:0x0064fd26  0x0064fd40

第二行打印两个数组的起始地址,第3行是地址加1的结果,等等。请注意地址是16进制的,因此,30比2f大1,比28大8。怎么回事?

ox0064fd20 + 1 等于 0x0064fd22 ?

0x0064fd30 + 1 等于 0x0064fd38 ?

真奇怪!我们的系统是按字节编址的,但是short类型使用2个字节,double类型使用8个字节。在C中,对一个指针加1的结果是对该 指针增加一个存储单元(storage unit)。对于数组而言,地址会增加到下一个元素的地址,而不是下一个字节。这就是在声明指针时必须声明它所指向对象的类型。计算机需要知道存储对象所用的字节数,所以只有地址信息是不够的(即使指针是指向标量的,也需要声明指针类型;否则*pt操作是不能正确返回数值的)。

现在我们能够清楚地定义指向int的指针、指向float的指针,以及指向其他数据对象的指针:

* 指针的数值就是它所指向的对象的地址。地址的内部表示方式是由硬件来决定的。很多种计算机都 是以字节编址的,这意味着对每个内存字节顺序进行编号。对于包含多个字节的数据类型,比如double类型的变量,对象的地址通常指的是其首字节的地址。

* 在指针前使用运算符*就可以得到该指针所指向的对象的数值。

* 对指针加1,等价于对指针的值加上它指向的对象的字节大小。

下面的等式体现出了C的优点:

dates + 2 == &dates[2];  //相同的地址

*(dates + 2) == dates[2]; //相同的值

这些关系总结了数组和指针间的密切关系:

可以用指针标识数组的每个元素,并得到每个元素的数值。从本质上说,对同一个对象有两种不同的符号表示方法。C语言标准在描述数组时,确实借助了指针的概念。例如,定义ar[n]时,意思是*(ar+n),即“寻址到内存中的ar,然后移动n个单位,再取出数值”。

顺便提一下,请注意区分*(dates + 2)和*dates + 2。间接运算符的优先级高于+,因此后都等价于*(dates)+2。

*(dates+2)  //dates的第3个元素的值

*dates + 2  //第一个元素的值和2相加

理解了数组和指针的关系,编程时就可以方便地选择两者中任意一种方法。例如程序清单10.9和程序清单10.1编译后的结果一样。

程序清单10.9  day_mon3.c 程序

/*day_mon3.c  --使用指针符号*/
#include <stdio.h>
#define MONTH 12

int main(void)
{
    int days[MONTH] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int index;
    
    for (index=0;index<MONTH;index++)
        printf("Month %2d has %d days.\n",index+1,
               *(days+index));  //与days[index]相同
    return 0;
}

此处,days是数组首元素的地址;days+index是元素days[index]的地址;*(days+index)是这个元素的值,与days[index]等价。

 

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
C Primer Plus 第10章 数组和指针 10.4 函数、数组和指针

假设您要编写一个对数组进行操作的函数,目的是要此函数返回数组内所有元素的和。假设marbles为这个int数组的名称。应该如何来调用这个函数? 一种合乎情理的猜测如下: totao = sum(marble...

idreamo
2016/07/28
59
0
C Primer Plus 第10章 数组和指针 10.7 指针和多维数组

指针和多维数组有什么关系?为什么我们需要知道它们之间的关系?函数是通过指针来处理多维数组的,因此在使用这样的函数之前,您需要更多的了解指针。假设有如下的声明: int zippo[4][2] ; ...

idreamo
2016/08/06
68
0
C Primer Plus 第10章 数组和指针 10.5 指针操作

C提供了6种基本的指针操作,下面的程序将具体演示这些操作。为了显示每一个操作的结果,程序将打印出指针的值(即指针指向的地址)、指针指向地址中存储的内容,以及指针本身的地址(如果您的...

idreamo
2016/07/30
77
0
C++ primer第二次阅读学习笔记(第4章)

C++语言应尽量使用vector和迭代器类型,应避免使用低级的数组和指针,涉及良好的程序只有在强调速度时才在类实现的内部使用数组和指针。因此要向成为一个真正的C++程序员就要多使用vector和s...

长平狐
2012/10/08
74
0
C Primer Plus 第10章 数组和指针 编程练习答案

1、修改程序清单10.7中的程序rain,使它不使用数组下标,而是使用指针进行计算(程序中仍然需要声明并初始化数组)。 2、编写一个程序,初始化一个double数组,然后把数组内容复制到另外两个...

idreamo
2016/08/14
262
0

没有更多内容

加载失败,请刷新页面

加载更多

面向海量数据的极致成本优化-云HBase的一体化冷热分离

前言 随着业务的持续发展,业务数据库存储量会持续增长。通常数据量过亿时,就需要考虑做分库分表,或者选择扩展能力更好的NOSQL/NewSQL数据库,如HBase就可以单表支持PB级数据,足够满足大多...

阿里云官方博客
32分钟前
3
0
最新最全国内外架构开源技术干货资料

大家好,废话不多说,整理了精心收集了各类资源。 声明,如侵犯个人利益,请联系小编,会立即删除相关资料。 领取方式在文末 求转发列表 好了,由于资源太多啦,就不一一列举了。 大家按照下...

泥瓦匠BYSocket
34分钟前
6
0
springmvc jsp访问不了css

在jsp中引入css,一直报404错误,直接访问css,也无法访问 将css文件移出WEB-INF,因为处于安全性考虑,这个目录禁止外部访问。 当引用css时,可以直接用绝对路径${pageContext.request.conte...

沉迷于编程的小菜菜
37分钟前
4
0
android 系统版本 9.1网络请求遇到坑

网络请求异常: E/http: CLEARTEXT communication to plat.xunlinkeji.cn not permitted by network security policy 在res下新建一个xml目录 创建名为network_security_config.xml 文件 ,该......

MrLins
54分钟前
5
0
Istio 1.3 发布,HTTP 遥测不再需要 Mixer

> 原文链接:Istio 1.3 发布,HTTP 遥测不再需要 Mixer Istio 是 Google、IBM 和 Lyft 联合开源的服务网格(Service Mesh)框架,旨在解决大量微服务的发现、连接、管理、监控以及安全等问题...

米开朗基杨
今天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部