C++程序设计 第八章 指针和引用

合集下载

c语言引用类型

c语言引用类型

c语言引用类型C语言是一种广泛应用于系统编程和嵌入式开发的高级编程语言。

它以其简洁、高效和灵活的特性而闻名。

在C语言中,引用类型是一种非常重要的概念,它允许程序员通过引用来访问和操作内存中的数据。

引用类型在C语言中有多种形式,包括指针、数组和结构体等。

这些引用类型的使用使得C语言能够更好地处理复杂的数据结构和算法。

首先,指针是C语言中最常用的引用类型之一。

指针是一个变量,其值为另一个变量的地址。

通过指针,我们可以直接访问和修改内存中的数据。

指针的使用可以提高程序的效率,尤其是在处理大量数据时。

例如,我们可以使用指针来传递数组或结构体,而不是复制整个数据。

这样可以节省内存空间和运行时间。

其次,数组也是一种常见的引用类型。

数组是一组相同类型的元素的集合。

通过数组,我们可以在内存中连续存储多个数据。

数组的使用使得我们可以更方便地处理大量数据。

例如,我们可以使用数组来存储学生的成绩,然后通过循环遍历数组来计算平均分数。

数组的索引从0开始,这意味着我们可以通过索引来访问数组中的每个元素。

最后,结构体是一种用户自定义的引用类型。

结构体是一种将不同类型的数据组合在一起的方式。

通过结构体,我们可以创建自己的数据类型,以便更好地组织和管理数据。

例如,我们可以使用结构体来表示一个学生,其中包含姓名、年龄和成绩等信息。

结构体的使用使得我们可以更好地组织和操作复杂的数据。

引用类型在C语言中的使用需要注意一些问题。

首先,我们需要确保引用的有效性。

在使用指针时,我们需要确保指针指向的内存是有效的。

否则,我们可能会访问无效的内存,导致程序崩溃或产生不可预测的结果。

其次,我们需要注意引用的生命周期。

在使用指针时,我们需要确保指针指向的内存在使用完毕后被正确释放,以避免内存泄漏。

最后,我们需要小心处理引用的边界情况。

在使用数组时,我们需要确保不会越界访问数组,否则可能会导致程序崩溃或产生不可预测的结果。

总之,C语言引用类型是一种非常重要的概念,它允许程序员通过引用来访问和操作内存中的数据。

《C语言程序设计》第8章指针

《C语言程序设计》第8章指针
}
10.3.3 指针变量和数组作函数参数 数组名作形参时,接收实参数组的起始地址;
作实参时,将数组的起始地址传递给形参数组。
引入指向数组的指针变量后,数组及指向数 组的指针变量作函数参数时,可有4种等价形式 (本质上是一种,即指针数据作函数参数):
(1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量、实参用数组名 (4)形参用数组名、实参用指针变量
(4)指针变量的++、--与&、*的结合
对于指针变量的++、--与&、*的结合 使用,关键要注意按照运算符的优先级和 结合性进行。
例如: int a=2, *p; p=&a;
•表达式:(*p)++,按运算符的优先级,等价于 a++。其含义为:取出指针变量p所指向的内存单 元的值(即a的值),a的值加1,送回a的内存单 元,a的值变为3,p的值未发生变化,仍然指向 变量a。
程序说明:printf("%s\n",s);语句 通过指向字符串的指针变量s,整体引
用它所指向的字符串的原理:系统首先输出s 指向的第一个字符,然后使s自动加1,使 之指向下一个字符;重复上述过程,直至遇到 字符串结束标志。
main() { char string[ ]=”I love Beijing.”; printf(“%s\n”,string); }
3.数组元素的引用 数组元素的引用,既可用下标法,也可用
指针法。
10.3.2 通过指针引用数组元素 如果有“int a [10],*p=a;” ,则: (1)p+i和a+i都是数组元素a [i]的地址。
(2)*(p+i)和*(a+i)就是数组元素a [i]。 int a [3]; a [0]——*a a [1]——*(a +1) a [2]——*(a +2)

精品课件-C程序设计(第三版)(荣政)-第8章

精品课件-C程序设计(第三版)(荣政)-第8章

第八章 指针
指针类型是对所有类型的指针的总称,指针的类型是指 针所指对象的数据类型。例如,pc是指向字符变量的指针, 简称字符指针。字符指针是基本类型的指针之一,除各种基 本类型之外,允许说明指向数组的指针、指向函数的指针、 指向结构体和共用体的指针以及指向各类指针的指针。在C 语言中只有指针被允许用来存放地址的值,其它类型的变量 只能存放该类型的数据。(很多书中用指针一词来指地址值, 或用指针变量来代表指针,阅读中应注意其具体含义。)
例8.2中指向整型的指针point在定义之后直接使用了,这 两条语句在编译时不会出现语法错误,但在使用时却几乎肯定 会出问题。表面上看,scanf()函数的参数要求给出的是地址, 而point的值就代表的是地址,但是point的值究竟是多少,也 就是说point究竟指向哪里,我们无法得知,在这种情况下就 对point指向的单元进行输入操作,将冲掉point指向的单元的 原有内容,假如这个单元是操作系统的所在处,就破坏了操作 系统,显然是一件危险的事。
为了理解指针的概念,程序员要有关于计算机如何在存储 器中存储信息的基本知识。以下简单地介绍个人计算机中存储 器存储的情况。
第八章 指针
个人计算机中CPU可以直接访问的,用来存储程序和数据 的记忆部件称为内存储器,内存储器由成千上万个顺序存储单 元组成,每个单元由一个惟一的地址标识。给定计算机的存储 器地址范围为从0到所安装的存储器数量的最大值。在计算机 上运行的每一个程序都要使用存储器。例如,操作系统要占用 一些计算机存储空间,每个应用程序也要占用计算机存储空间。 按照面向过程的结构化程序设计方法,程序代码和程序要处理 的数据是分开存储的,所以,一个程序在内存中要占两部分空 间:数据部分和指令代码部分。
第八章 指针

C二级 第8章 指针

C二级 第8章 指针

1.以下定义语句中正确的是A) int a=b=0; B) char A=65+1,b='b';C) float a=1,*b=&a,*c=&b; D) double a=0.0; b=1.1;参考答案:B【解析】A选项语句中b变量还没有定义不能直接用于给a变量赋值。C选项语句中*b、*c表示的是一个实型变量的地址,不能再将&b赋值给指针型变量c。D选项语句中a=0.0后面应该为逗号,不能是分号。2.有以下程序#include <stdio.h>void f(int *p,int *q);main(){ int m=1,n=2,*r=&m;f(r, &n);printf("%d,%d",m,n);}void f(int *p,int *q){ p=p+1;*q=*q+1;}程序运行后的输出结果是A) 2,3 B) 1,3 C) 1,4 D) 1,2参考答案:B【解析】在f(int *p,int*q)函数中,执行p=p+1是将p所对应的地址加1,而*q=*q+1是将q所指向的n的地址所对应的值加1,所以m的得知所对应的值没有变,而n的值则为3了。

因此B选项正确。

3.以下叙述中正确的是A) 如果p是指针变量,则&p是不合法的表达式B) 如果p是指针变量,则*p表示变量p的地址值C) 在对指针进行加、减算术运算时,数字1表示1个存储单元的长度D) 如果p是指针变量,则*p+1和*(p+1)的效果是一样的参考答案:C【解析】B选项中,如果p是指针变量,则*p表示变量p所指向的地址的值;A选项中,如果p是指针变量,则&p表示变量p的地址;D选项中,如果p是指针变量,*p+1表示将p所指的值加上1,而*(p+1)表示的是先将指针右移一位再取所指向变量的值。

因此C选项正确。

4.以下叙述中正确的是A) 基类型不同的指针变量可以相互混用B) 函数的类型不能是指针类型C) 函数的形参类型不能是指针类型D) 设有指针变量为double *p,则p+1 将指针p移动8个字节参考答案:D【解析】B选项中,所谓函数类型是指函数返回值的类型。

高树芳C语言程序设计--第八章

高树芳C语言程序设计--第八章

30
8.5 知识拓展
案例8-11 指针的高级应用 [案例任务] 阅读下列程序 ,分析运行结果,了解指 针的各种应用。
程序代码
31
8.5 知识拓展
相关知识:
1.有关指针的数据类型小结 2.案例说明 3.main函数的参数
32
12
8.2 指针变量
[课堂训练8-1] void swap(int *p1,int *p2) { int *t; t=p1; p1=p2; p2=t; }
1.分析下面的程序,写出运行结果。 #include <stdio.h> void main() { void swap(int *p1,int *p2); int *p1,*p2,a=6,b=8; p1=&a; p2=&b; printf(" 交换前:*p1=%d,*p2=%d\n",*p1,*p2); swap(p1,p2); printf(" 交换后:*p1=%d,*p2=%d\n",*p1,*p2); }
17
8.3 指针与数组
案例8-6 [案例任务]
冒泡排序
使用指针指向一维整型数组,使用冒泡排 序法对数组元素从小到大排序并输出。
程序代码
18
8.3 指针与数组
相关知识: 1.冒泡排序法 2.指针变量的其他运算
19
8.3 指针与数组
案例8-7 [案例任务]
逆置一维数组
使用数组名或指针变量作为函数形参与实 参,完成一维数组元素的逆置。请分析程 序运行结果,并对两个方法进行比较。
6
8.2 指针变量
案例8-2 用指针交换两整数 案例8-3 用指针比较两数大小 案例8-4 用指针参数交换两整数

c语言指针的引用类型

c语言指针的引用类型

c语言指针的引用类型C语言是一种广泛使用的编程语言,它的指针类型是其特有的一种引用类型。

指针是一种存储变量地址的数据类型,它允许程序直接访问内存中的数据。

在C语言中,指针的引用类型包括指针、引用和指针的指针,它们在程序中起着不同的作用。

首先是指针,它是存储变量地址的数据类型。

通过指针,程序可以直接访问内存中的数据,而不需要将数据复制到另一个位置。

指针的引用类型使得程序可以更加高效地处理数据,尤其是在处理大量数据时,指针可以节省内存空间和运行时间。

其次是引用,引用是一种特殊的指针,它允许程序直接访问变量的值。

引用可以被用来传递参数、返回值和在函数中修改变量的值。

引用类型使得程序可以更加方便地操作变量,而不需要在不同的函数之间频繁地复制数据。

最后是指针的指针,它是指向指针的指针。

指针的指针在C语言中被广泛应用于多级指针和动态内存分配。

多级指针可以用来处理多维数组和复杂的数据结构,而动态内存分配可以使程序更加灵活地管理内存空间。

总的来说,C语言的指针引用类型在程序设计中起着至关重要的作用。

它们使程序更加高效、灵活和方便,尤其是在处理大量数据和复杂数据结构时。

对于C语言的学习者来说,掌握指针的引用类型是非常重要的,它可以帮助他们更好地理解和使用C语言,同时也可以提高程序的性能和可维护性。

在实际的程序设计中,程序员需要谨慎地使用指针的引用类型,避免出现指针悬挂和内存泄漏等问题。

同时,程序员还需要充分理解指针的引用类型的概念和用法,以便更好地利用它们解决实际的问题。

只有在深入理解和熟练掌握了指针的引用类型之后,程序员才能写出高质量、高效率的C语言程序。

C语言程序设计(第3版)何钦铭-颜-晖-第8章--指针

C语言程序设计(第3版)何钦铭-颜-晖-第8章--指针

第8章指针【练习8-1】如果有定义”int m, n = 5, *p = &m;”与m = n等价的语句是B 。

A.m = *p; B. *p = *&n; C. m = &n; D. m = **p;解答:A:p是指向m的指针变量,所以*p等价于m。

即m=m。

B:&n是n的地址,*&n是n的值,即把n的值赋给p指向的值m。

即m=n。

C:&n是n的地址。

即把n的地址赋给m。

D:**p是指p指向的指针所指向的值,在此无意义。

故选B。

【练习8-2】调用函数求两个数的和与差:计算输入的两个数的和与差,要求自定义一个函数sum_diff(float op1,float op2, float *psum, float *pdiff),其中op1和op2是输入的两个数,*psum 和*pdiff 是计算得出的和与差。

解答:#include<stdio.h>void sum_diff(float op1,float op2,float *psum,float *pdiff);int main(void){float op1,op2,sum,diff;printf("Input op1 and op2: ");scanf("%f%f",&op1,&op2);sum_diff(op1,op2,&sum,&diff);printf("%f+%f=%f;%f-%f=%f \n",op1,op2,sum,op1,op2,diff);return 0;}void sum_diff(float op1,float op2,float *psum,float *pdiff){*psum=op1+op2;*pdiff=op1-op2;}【练习8-3】两个相同类型的指针变量能不能相加?为什么?解答:不能。

第08章 变量的间接访问——指针 (《程序设计基础(第3版)(C语言)》(王红梅著 清华大学出版社

第08章 变量的间接访问——指针  (《程序设计基础(第3版)(C语言)》(王红梅著 清华大学出版社

/*指针p指向变量x */
( 第
int *q = p ;
/*指针q指向变量p所指向的变量x*/
版 )


x(*p)
大 学

x(*p)
p
10
版 社
p
10
q
3
Page 14
8.1 指针的概念 指针变量的初始化
3
int x = 10; double *q = &x;
/*指针q的基类型是double,不能指向int型变量*/
大 学

计算机系统和编译器有关。
版 社
(3)定义指针变量时需要明确该指针所指向的数据类型,即该指针所指向的内
存单元可以存放什么类型的数据,对指针变量的运算与它所指向的数据类型密
切相关。
Page 11
8.1 指针的概念
指针变量的初始化
3
例如: int *p ;
int *p = NULL ;
/*NULL为空指针*/
出 版
int *p = NULL, *q = NULL;
/*指针p和q均初始化为空*/

p = &x;
/*指针p指向变量x*/
q = p;
/*指针q指向指针p所指内存单元*/
3
Page 17
8.1 指针的概念
指针变量的操作
1. 指针变量的赋值
通常不允许将一个整数赋给指针变量,由于指针的操作需要编程人员保
指针变量的初始化
3
【语法】初始化指针变量的一般形式如下:
基类型 *指针变量名 = 内存地址 ;
程 序 设



【语

】定

C语言程序设计教程第8章北京邮电大学出版社.

C语言程序设计教程第8章北京邮电大学出版社.

第8章 指针
18
说明: 对于不同基类型的指针,指针变量“加上” 或“减去”一个整数n所移动的字节数(= sizeof( 指针所指对象的数据类型 ) )是不同的。 例如: float a[10], *p=a, *x; x=p+3; /*实际上是p加上3*4个字节赋给x, x依然指向数组的第三个分量*/
C语言程序设计教程
第 8 章 指针
8.1 8.2 8.3 8.4 8.5 8.6 指针与指针变量 指针与函数 指针与数组 指针与字符串 指针数组与命令行参数 程序举例
第8章 指针
2
8.1 指针与指针变量
8.1.1 指针的概念
1.内存与变量地址 内存地址:内存是计算机用于存储数据的存储 器,以一个字节作为存储单元,为了便于访问,给 每个字节单元一个唯一的编号,第一字节单元编号 为0,以后各单元按顺序连续编号,这些单元编号 称为内存单元的地址 。 变量地址:变量所分配存储空间的首字节单元 地址(字节单元编号)。
2018/9/14
C语言程序设计教程
第8章 指针
3
在程序中,对变量的操作实际上是通过地址来完成的。 • 定义时:定义变量→分配内存单元(按类型)→地址 (即内存中的编号) • 存取操作:程序 →变量名 →内存单元 →存取 • 实际上: 程序 →编译 →变量名 →变量的地址
2.访问方式
直接存取:把直接按变量名或地址存取变量值的方式 称为 “直接存取”方式。
2018/9/14
C语言程序设计教程
第8章 指针
10
8.1.3 指针运算
指针运算实际上是地址的计算,包括赋值运算、算术运算、 关系运算三种。
1. 指针的赋值运算 (1)将变量地址值赋给指针变量,使指针指向该变 量。

c语言的引用类型

c语言的引用类型

c语言的引用类型C语言是一种非常受欢迎的编程语言,它的灵活性和高效性使其成为开发各种应用程序的首选语言之一。

在C语言中,有两种主要的数据类型:值类型和引用类型。

值类型代表的是实际的数据值,而引用类型则是指向存储在内存中的对象的指针。

引用类型在C语言中起着非常重要的作用。

它允许我们通过引用来访问和操作对象,而不是直接访问对象本身。

这种间接的访问方式使得我们能够更加灵活地操作对象,并且可以节省内存空间。

在C语言中,引用类型主要包括指针和数组两种形式。

指针是一种特殊的变量,它存储了一个内存地址。

通过使用指针,我们可以直接访问这个地址所指向的对象,并对其进行操作。

通过指针,我们可以动态地分配和释放内存,以满足程序的需要。

指针在C语言中的应用非常广泛,几乎无处不在。

数组是一种引用类型,它由相同类型的元素组成,这些元素在内存中是连续存储的。

通过访问数组的第一个元素的地址,我们可以通过偏移量来访问数组中的其他元素。

数组在C语言中的应用非常广泛,它可以用来存储和处理大量的数据。

引用类型在C语言中有着众多的优点。

首先,它们允许我们通过引用来访问和操作对象,而不需要复制整个对象。

这样可以节省内存空间,并提高程序的运行效率。

其次,引用类型还允许我们动态地分配和释放内存,以满足程序运行时的需要。

最后,引用类型还可以用来传递和共享数据,在函数调用和模块间通信时非常有用。

当然,引用类型也有一些需要注意的地方。

首先,由于引用类型允许对内存进行动态分配和释放,所以需要特别注意内存泄漏和指针悬挂的问题。

其次,由于引用类型的操作是直接访问内存而不经过边界检查,所以需要特别注意指针越界访问和野指针的问题。

最后,引用类型的操作也可能导致并发访问的问题,需要采取合适的同步机制来保证数据的一致性。

在实际的程序开发中,引用类型是非常常用的。

无论是简单的变量引用,还是复杂的数据结构和算法,引用类型都可以发挥重要作用。

对于初学者来说,了解引用类型的概念和使用方法是非常重要的,它可以帮助我们更好地理解和掌握C语言的编程技巧。

C语言程序设计(第二版)-电子教案-丁亚涛-8587 第8章 指针

C语言程序设计(第二版)-电子教案-丁亚涛-8587 第8章 指针
}
8.5.3 指针与二维数组
• 二维数组其实可以看成由一维数组构造而成。就相当于 几个队列构成一个方阵,方阵由队列组成,队列由具体 的元素--人组成。
• 一级指针只能管理队列,如果管理方阵,则需要二级指 针。
•int a=1000,*pa,**ppa; • pa=&a; • ppa=&pa;
• *(*(ppa)) ≡ *(pa) ≡ a ≡ 1000
• p是二级指针 • *p相当于*(p+0),级别降低为一级指针,相当于p[0] • **p相当于*(*(p+0)+0),级别降低为数组元素(普通变量),
也相当于p[0][0]
• p[1][2],相当于*(*(p+1)+2) • &p[1][2], 级别提升为一级指针,相当于:
• p[1]+2,*(p+1)+2 • &p[1],级别提升为二级指针,相当于:
f=f4; printf("a/b=%d\n",f(a,b));
8.5 指针与数组
• 8.5.1 指针与字符数组 • char str[100]= "Hello World"; • char *p=str; • 字符w可以有如下多种表示形式: • str[6] • *(str+6) • p[6] • *(p+6)
【例8-2】演示指针和数组的关系。
#include <stdio.h>
接可存取,由于p中存储的是x的信息。访问p可以获取x的信 息,再对银行存款进行操作。
8.1 借钱的故事
8.2 指针的概念
• C语言允许使用变量名、数组名[下标]、函数名等标 识符来访问内存

C语言程序设计第八章 指针的使用

C语言程序设计第八章 指针的使用

第八章指针的使用【学习目标】本章将详细介绍在C语言中如何使用指针。

学习要点包括如下几点:(1)掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。

(2)掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量。

(3)熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。

(4)了解指针与字符串的关系,能熟练使用指针处理字符串。

(5)熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。

(6)指向指针的指针的运用。

【学习导航】本章的在整个课程中的位置如图5-1所示。

图8-1 本章学习导航在本书的第一章介绍C语言有一个灵活性的特点,那么它的灵活性具体体现在哪里呢?其实就是指针。

指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。

有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效。

8.1 地址和指针指针是C语言的一种数据类型,类似于整型、字符型等。

既然指针也是一种类型,那么也可以定义该类型的变量,称为指针变量。

指针变量和其他类型的变量的区别是:指针变量存储的是地址。

所以要学好指针,就一定要明白数据在内存中是如何存储的。

计算机所有数据都是存储在存储器里,系统的内存可看作编了号的小房间,如果要取房间的东西(读取数据)就需要得到房间编号。

地址就是内存区中对每个字节的编号。

下面通过两个整型变量来说明。

整型变量x、y(基本整型需4个字节)在内存中的存储如图8-2所示(假设内存编号是从2000开始)。

把变量所占用的存储单元首字节的地址作为变量的地址。

C语言中利用取地址运算符“&”获取变量的存储地址。

例如,&c将返回c的首地址;&x将返回x的首地址。

2000H2004H2008H2012H...图8-2 变量x和y在内存中的存储图8-2中2000H和2004H就是内存单元的地址。

举例说明指针的定义和引用指针所指变量的方法

举例说明指针的定义和引用指针所指变量的方法

举例说明指针的定义和引用指针所指变量的方法摘要:一、指针的定义二、引用指针所指变量的方法三、指针在实际编程中的应用示例正文:在计算机编程中,指针是一种非常重要且实用的概念。

它是一种存储变量地址的数据类型,通过指针可以间接访问和操作内存中的数据。

下面我们将详细介绍指针的定义、引用指针所指变量的方法以及指针在实际编程中的应用。

一、指针的定义在C/C++等编程语言中,指针是一种特殊的数据类型,它的值表示另一个变量在内存中的地址。

指针变量声明的一般形式为:`typedef int*ptr_to_int;`其中,`int`表示指针所指变量的数据类型,`ptr_to_int`表示指针变量。

声明指针后,我们需要为其分配内存空间,这可以通过`malloc`等内存分配函数实现。

二、引用指针所指变量的方法在实际编程中,我们通常需要通过指针来操作所指变量。

引用指针所指变量的方法有两种:1.直接访问:使用`*`运算符,如`*ptr = 10;`表示将10赋值给指针ptr所指的变量。

2.间接访问:使用`->`运算符,如`ptr->name = "张三";`表示将字符串"张三"赋值给指针ptr所指的结构体中的name成员。

三、指针在实际编程中的应用示例1.动态内存分配:在程序运行过程中,根据需要动态分配内存空间,如使用`malloc`分配内存,然后通过指针访问和操作分配的内存。

2.函数参数传递:使用指针作为函数参数,可以实现函数对实参的修改,如`void swap(int *a, int *b);`这个函数接受两个整型指针作为参数,实现两个整数的交换。

3.链表:在链表中,每个节点都包含一个指向下一个节点的指针,通过遍历链表的指针,可以实现对链表中数据的访问和操作。

4.结构体:结构体中的成员可以是不同类型的数据,通过指针可以访问结构体中的各个成员,如在学生信息管理系统中,可以使用指针访问学生姓名、年龄等成员。

C语言结构体指针引用详解

C语言结构体指针引用详解

C语⾔结构体指针引⽤详解⽬录指向结构体变量的指针指向结构体数组的指针结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针。

指向结构体变量的指针前⾯我们通过“结构体变量名.成员名”的⽅式引⽤结构体变量中的成员,除了这种⽅法之外还可以使⽤指针。

前⾯讲过,&student1 表⽰结构体变量 student1 的⾸地址,即 student1 第⼀个项的地址。

如果定义⼀个指针变量 p 指向这个地址的话,p 就可以指向结构体变量 student1 中的任意⼀个成员。

那么,这个指针变量定义成什么类型呢?只能定义成结构体类型,且指向什么结构体类型的结构体变量,就要定义成什么样的结构体类型。

⽐如指向 struct STUDENT 类型的结构体变量,那么指针变量就⼀定要定义成 struct STUDENT* 类型。

下⾯将前⾯的程序⽤指针的⽅式修改⼀下:# include <stdio.h># include <string.h>struct AGE{int year;int month;int day;};struct STUDENT{char name[20]; //姓名int num; //学号struct AGE birthday; //⽣⽇float score; //分数};int main(void){struct STUDENT student1; /*⽤struct STUDENT结构体类型定义结构体变量student1*/struct STUDENT *p = NULL; /*定义⼀个指向struct STUDENT结构体类型的指针变量p*/p = &student1; /*p指向结构体变量student1的⾸地址, 即第⼀个成员的地址*/strcpy((*p).name, "⼩明"); //(*p).name等价于(*p).birthday.year = 1989;(*p).birthday.month = 3;(*p).birthday.day = 29;(*p).num = 1207041;(*p).score = 100;printf("name : %s\n", (*p).name); //(*p).name不能写成pprintf("birthday : %d-%d-%d\n", (*p).birthday.year, (*p).birthday.month, (*p).birthday.day);printf("num : %d\n", (*p).num);printf("score : %.1f\n", (*p).score);return 0;}输出结果是:name : ⼩明birthday : 1989-3-29num : 1207041score : 100.0我们看到,⽤指针引⽤结构体变量成员的⽅式是:(*指针变量名).成员名注意,*p 两边的括号不可省略,因为成员运算符“.”的优先级⾼于指针运算符“*”,所以如果 *p 两边的括号省略的话,那么*p.num 就等价于 *(p.num) 了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C++

在程序运行时变量和函数都存放在内存中,通过变量名来访问数据、通过函数名来调用函数都是直接访问方式。还有另一种间接访问方式就是用指针。指针的本质是内存地址。指针往往用于说明函数的形参,使实参能通过指针传递,以提高函数调用的效率。利用指针能动态地使用内存,以提高内存使用效率。指针也能用来表示数据关联,以构成复杂的数据结构。指针是C程序中最常见的类型。引用是C++扩展的新概念,主要用于函数形参和返回类型。本章将详细介绍指针和引用的概念及应用。
首先,这6个变量的地址是按递减次序排列,这是因为局部变量都存储在堆栈中,堆栈是先入后出的。先入栈的数据存放在较大地址位置,后入栈的数据存放在较小地址位置。如果这些变量改为全局变量,它们的排列次序就会颠倒过来。
其次,尽管变量s只占2字节,变量c只占1字节,但却分别占用4字节空间。这是因为按字对齐(32位数据)能提高CPU访问内存的效率,而且一次压栈和出栈操作也是以32位数据为单位,代价是浪费一些内存。如果这些变量改为全局变量,它们将按实际大小存储。
怎样能知道一个变量在运行时刻的内存地址?把取地址运算符&放在变量前面就得到它的首地址。例如b是一个变量,那么&b就表示它的地址。下面例子能看到一组局部变量的首地址。
例8-1显示一组局部变量的首地址。
#include<iostream.h>
void main(){
bool b = true;
char c = 'c';
其中,<类型名>是这个指针变量所指向的对象的类型,简称指针类型,它可以是任何一种类型。*表示这个变量是一个指针变量。这个变量的类型就是“<类型名>*”。<变量名>是一个标识符。指针变量可以进行初始化,等号之后给出一个变量的地址,要求这个变量的类型与指针类型相符。
假设程序中说明了一个变量int i = 4,而且在运行时该变量i的地址为0X0012FF70。
在一个变量说明语句中,或者一个函数形参表中,一个变量或形参之前加一个“*”,就说明了该变量或该形参是一个指针类型。注意这里的“*”是一个说明符号,并非一个运算符,区别于“*”作为双目乘法运算符。下面还将介绍“*”作为单目运算符的第三种用法。
8
既然指针就是地址,那么指针的运算实际上就是地址的运算。但由于地址是特殊的数据,使指针所能进行的运算受到一定限制。对于指针只能进行赋值运算、间接引用运算、算术运算、两个指针间的减运算和关系运算。
如果一个指针变量存放的是某个对象或值的地址,就说这个指针变量指向该对象或值。在C++程序设计中,指针变量只有确定了指向才有意义。
8
指针变量就是专门存放地址的一种特殊变量。指针变量中存放的是地址值。一个指针的值就是一个地址。
指针变量与其它变量一样,在使用之前必须先说明。说明指针变量的格式为:
<类型名> *<变量名> [= &<变量>];
例如:
int *ip1, i2;//说明一个指针变量ip1(其类型为int *)和一个int变量i2
float *fp;//说明一个指针变量fp(其类型为float *)
指针变量ip1所指向的变量的类型为int型,指针变量fp所指向的变量的类型为float型。
下面说明指针变量的几种写法都是合法的。
int *p;// *与类型名之间有空格,与变量名p之间没有空格
8.1
指针(pointer)的本质是内存地址。指针变量就是专门存储地址的一种变量。通过指针变量所存储的地址来访问数据是一种间接寻址方式。由于处理器的机器语言能支持间接寻址,所以使用指针可以达到较高的计算性能。
8
C++编译器对不同对象或变量按其数据类型分配合适大小的存储空间。例如为char或bool型变量分配1个字节(bytes)的存储空间,short分配2字节,int和float分配4个字节,为double型变量分配8个字节的存储空间。当程序执行时,代码和变量都加载到内存中。计算机内存被分成若干个存储单元,存储单元以字节为单位。每个存储单元都有一个固定的编号,这个编号就是内存地址。尽管一个变量可能占用多个字节空间,但都通过第一个字节的地址来访问。存放ቤተ መጻሕፍቲ ባይዱ个变量的第一个字节的地址就是该数据的首地址。
cout<<"&d="<<&d<<endl;
}
执行程序,输出如下:
&b=0x0012FF7C
&c=12ff78
&s=0x0012FF74
&i=0x0012FF70
&f=0x0012FF6C
&d=0x0012FF64
注意在不同机器上或不同时刻运行,显示的地址都不一样。但我们能看到局部变量在内存中的一些排列规律。如图8.1所示。
指针即内存单元的地址,而数据是内存单元中的内容(或值)。
假设在程序中说明了1个int型的变量a,其值为68。系统为变量a分配4字节的存储空间,设首地址为0X0065FDF4。通过地址0X0065FDF4就能找到变量a在内存中的存储单元,从而对变量a进行访问。0X0065FDF4就是变量a的指针。知道一个变量的地址和变量的类型就能对变量进行访问,就如同知道房间号就能找到房间,从而找到房间里的主人。
*d = *d * *d;//C等价于*d =(*d)*(*d);
}
void main(){
double d1 = 2.2;//D
square(&d1);//E
cout<<d1<<endl;//F
}
上面A行定义了一个函数square,其形参为一个double型指针。此函数对指针所指向的某个double变量求平方。此函数没有返回值。B行先判断形参指针不为空,这是指针作为形参的通常处理方法,目的是防止通过空指针进行有害操作。C行包含了间接引用运算符、乘法运算符和赋值运算符,完成平方计算。注意C行并没有改变指针d,而是改变了指针d所指向的调用方实参的值。
同一个变量在不同机器上执行或在不同时刻执行,其地址都不一样。这是因为在加载一个程序时,系统根据当前可用内存来确定使用哪一块内存。在编程中一个具体的地址值没有多大意义,不应该直接用一个地址常量来为一个指针赋值,这是因为在运行时你不知道这个地址中当前存放的是什么。如果你通过这个地址读取它的内容,将得到不可预知的结果。如果你改变了它的内容,就会导致不可预知的后果,甚至导致严重错误而退出。所以对指针的操作应小心谨慎。
至此,“*”有三种不同的含义,随其所作用的对象及位置的不同而不同。例如:
int a = 16, b = 28;
int *pa = &a, *pb;//*表示pa、pb是指针变量,指针说明
a *= a * b;//*表示乘法运算,双目运算符
*pa = 123;//*表示间接引用pa所指向的对象a,单目运算符
short s = 3;
int i = 4;
float f =1.0f;
double d = 1.0;
cout<<"&b="<<&b<<endl;
cout<<"&c="<<hex<<(int)&c<<endl;
cout<<"&s="<<&s<<endl;
cout<<"&i="<<&i<<endl;
cout<<"&f="<<&f<<endl;
说明一个指针变量:
int * pa = &i;
此时指针变量pa中就存放了变量i的地址,即pa中存放的值为0X0012FF70。我们称pa指针指向了变量i。如图8.2所示。
现在访问变量i就有两种方式:一是按变量名i来访问。将变量名i转换为一个相对地址,在运行时经动态定位得到i的地址0X0012FF70,再找到i的存储单元。二是通过指针变量pa来访问。按pa变量的地址先找到pa,然后根据pa的值再找到变量i的存储单元,从而对变量i进行访问。前一种访问方式称为直接寻址,后一种称为间接寻址。间接方式的好处是一个指针pa在不同时刻可指向不同的整数变量,这样通过一个指针变量就能访问多个数据。
注意,赋值运算还隐含在函数调用时,实参值传递给形参也是一种赋值。
2
对于一个指针变量,就能通过它的值来访问对应地址的值。这种由地址求内容的过程就是间接引用运算。“*”作为一种单目运算符,作用于一个指针变量,就是按该指针的地址求值(英文称dereference,含义是去引用,习惯称为间接引用)。例如:
int a = 16, b = 28;
NULL是一个宏,其值为0,说明在多个头文件中,例如<iostream.h>中包含的<ios.h>。值为NULL的指针称为空指针。当一个指针变量暂时无法确定其指向或暂时不用时,可将它赋予NULL。在使用一个指针前应判定不能为空,以保证程序正常执行。
在为指针赋值时应保证指针类型的一致性。例如,你不能把一个int变量的地址赋给一个float指针,反之也不行。即便你使用强制类型转换能通过编译,也会在运行时出现错误。
int *pa, *pb = &b;
cout<<*pb<<endl;//输出pb所指对象b的值28
pa = &a;
cout<<a<<endl;//输出a的值16
*pa = 32;//修改pa所指对象a的值,使a的值变成32
相关文档
最新文档