第10章 指针
(main)
9 5 9 9 2000 2002
(swap)
2000 2002 ****
...
指针变量在使用前 必须赋值!
…...
整型变量a 整型变量b 指针pointer_1 指针pointer_2 指针p1 指针p2 指针p
假设2000
例 将数从大到小输出
…...
/*ch9_32.c*/ swap(int x,int y) { int t; t=x; x=y; y=t; 值传递 } main() COPY { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(*pointer_1,*pointer_2); printf("\n%d,%d\n",a,b); }
危险!
…...
2000 2001 2002 2003 2004 2005 2006 …... 随机
整型变量i
10
指针变量p
例 main( ) { int i=10,k; int *p; p=&k; *p=i; printf(“%d”,*p); }
零指针与空类型指针
零指针:(空指针)
定义:指针变量值为零 表示: int * p=0;
地址存入 指针变量
&与*运算符
含义 含义: 取变量的地址 含义: 取指针所指向变量的内容 两者关系:互为逆运算 单目运算符 单目运算符 i_pointer 优先级: 理解 2 优先级: 2 &i_pointer 2000
结合性:自右向左 结合性:自右向左 …... 2000 2001 2002 *i_pointer 10 i
指针变量的初始化
一般形式:[存储类型] 数据类型 *指针名=初始地址值; 例 int i; int *p=&i; 赋给指针变量, 不是赋给目标变量 变量必须与已说明过的 类型应一致
例
例 int i; int *p=&i; int *p=&i; int i; int *q=p;
用已初始化指针变量作初值
main() { int a; int *pa=&a; a=10; printf("a:%d\n",a); printf("*pa:%d\n",*pa); printf("&a:%x(hex)\n",&a); printf("pa:%x(hex)\n",pa); printf("&pa:%x(hex)\n",&pa); }
(main)
…...
5 9
变量a 变量b
} main() { int a,b; scanf("%d,%d",&a,&b); if(a<b) swap(a,b); printf("\n%d,%d\n",a,b); 运行结果:5, 9 }
200A
…...
例 将数从大到小输出 swap(int *p1, int *p2) { int p; p=*p1; *p1=*p2; *p2=p; } main() COPY { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b)swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); }
(main) …...
5 9
(swap)
变量a 变量b 变量x
5 9 5 9 5
…...
变量y
变量temp
指针变量作为函数参数——地址传递
特点:共享内存,“双向”传递 例 将数从大到小输出 swap(int x,int y) 2000 { int temp; 2002 temp=x; 2004 x=y; 2006 y=temp; 2008 值传递
例 main( ) { int i; static int *p=&i; ..............
}
( )
不能用auto变量的地址 去初始化static型指针
指针变量必须先赋值,再使用 例 main( ) { int i=10; int *p; *p=i; printf(“%d”,*p); }
i k
2005
…...
变量是对程序中数据 存储空间的抽象
指针与指针变量
指针:一个变量的地址 指针变量:专门存放变量地址的变量叫~
指针 2000 …... 整型变量i
变量的地址
2001
10
变量的内容
2002
2003 2004 2005 2000 2006 指针变量 变量地址(指针) 指向 变量 变量值 …... 变量i_pointer 指针变量
2000 变量i 3 *i_pointer
i &i
i=3;
*i_pointer i_pointer
*i_pointer=3
指针变量的定义
一般形式: [存储类型] 例 数据类型 *指针名; int *p1,*p2; 表示定义指针变量 float *q ; 合法标识符 指针变量本身的存储类型 指针的目标变量的数据类型 不是‘*’运算符 static char *name; 注意: 1、int *p1, *p2; 与 int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值
p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较
void *类型指针
表示: void *p; 使用时要进行强制类型转换
表示不指定p是指向哪一种 类型数据的指针变量
例 指针的概念 …... 运行结果: a:10 *pa:10 &a:f86(hex) pa:f86(hex) &pa:f88(hex)
f86 f87 f88 f89 f8a f8b f8c …... f86
整型变量a 指针变量pa
10
例 输入两个数,并使其从大到小输出
main() { int *p1,*p2,*p,a,b; 2000 scanf("%d,%d",&a,&b); 2002 p1=&a; p2=&b; 2004 if(a<b) 2006 { p=p1; p1=p2; p2=p;} 2008 printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); }
运行结果:5,9 (main) …... ...
5 9 2000 2002
运行结果:5,9
(main)
2000 2002
2004 2006 2008 200A 200C 200E 2010
5 9 2000 2002
(swap)
整型a 整型b pointer_1
pointer_2
整型x 整型b 整型t
9 5 9 5 5
...
例 将数从大到小输出 swap(int *p1, int *p2) { int *p; 2000 p=p1; 2002 p1=p2; p2=p; 2004 地址传递 } 2006 main() 2008 COPY { int a,b; 200A int *pointer_1,*pointer_2; 200C scanf("%d,%d",&a,&b); 200E pointer_1=&a; pointer_2=&b; 2010 if(a<b) swap(pointer_1,pointer_2); printf("%d,%d",*pointer_1,*pointer_2); }
第十章 指针
C程序设计中使用指针可以:使程序简洁、紧 凑、高效
有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值
§10.1 指针的概念
变量与地址
内存中每个字节有一个编号-----地址 内存 0
程序中: int i;
float k;
编译或函数调用时为其分配内存单元
…...
2000 2001 2002 2003
直接访问与间接访问
直接访问:按变量地址存取变量值 间接访问:通过存放变量地址的变量去访问变量
…...
例
整型变量i
i=3;
-----直接访问
2000 2001 2002 2003 2004 3 20 10
变量i_pointer
2000
2005
2006
指针变量
例
*i_pointer=20;
Байду номын сангаас
-----间接访问
p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义 例 例 char *p1; int *p; ...... void *p2; while(p!=NULL) p1=(char *)p2; { ...… p2=(void *)p1; }
#define NULL 0 int *p=NULL:
运行结果:9,5 (main) 2000 2002 2004 …...
2006 2008
200A 200C 200E 2010
C语言程序设计_谭浩强_第二版_CH10
}
第十章 指针 10.3 数组的指针和指向数组的指针变量 10.3.2 通过指针引用数组元素 例10.5输出数组中的全部元素。 ②通过数组名计算数组中元素的地址,找出元素的值。
main() {
int a[10],i; for(i=0;i<10;i++){scanf(“%d”,&a[i]);} print(“\n”); for(i=0;i<10;i++){printf(“%d”,*(a+i));} print(“\n”);
}
运行结果为: 100,10 100,10
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.1 通过指针变量访问整型变量
pointer_1 &a
a 100 *pointer_1
pointer_2 &b
b 10 *pointer_2
第十章 指针 10.2 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
pointer_1 &a
a 5 *pointer_1
pointer_2 &b
b 9 *pointer_2
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
b 5 *pointer_2
&b
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
pointer_1 &a
a 9 *pointer_1
第十章 C++ 基础
华厦职业学院
C语言程序设计
其中public是成员的属性说明,表示公有成员, 类的成员还可以声明为private(私有成员)或 protected(保护成员),不同属性的成员在访问时 规则不同。 类定义好之后,可以像结构那样定义变量,方 法是: 类的名称 变量名称;
华厦职业学院
C语言程序设计
在C++中类定义的变量称为对象(object),在定 义对象时,也可以用类名来定义类变量的指针,注 意在使用时类名称之前不写class。例如: time t; // t是类time的一个对象; time *pt; // pt是一个指向类对象的指针
华厦职业学院
C语言程序设计
关于成员函数,有以下规则: (1) 成员函数是类的函数,不能独立执行,必须要 用一个对象或对象指针来调用执行,什么对象调用 成员函数,成员函数就作用于什么对象,既成员函 数的执行结果依赖于具体的对象; (2) 成员函数中可以存取同一个类中的成员变量, 这些成员变量就是相应对象的成员变量;成员函数 也可以调用同一个类中的其它成员函计
10.3
构造函数与析构函数
10.3.1 构造函数 用类来定义对象变量时,往往需要让对象有一个初始值, 完成这种功能的函数就是构造函数。构造函数是与类同名的 函数,但函数没有任何返回类型,也不是void类型,例如: class time { public: int h,m,s; time() { h=0; m=0; s=0; } void set(int th,int tm,int ts) { h=th; m=tm; s=ts; } void show(); };
华厦职业学院
C语言程序设计
10.1 类与对象 10.2 this指针 10.3 构造函数与析构函数 10.4 引用与复制构造函数 10.5 动态内存分配 10.6 类成员的访问规则 10.7 对象的赋值 10.8 运算符重载
c语言 ●第10章 指针-1
…
19
2.定义时同时赋值
int a[10];
int *p=a; c规定: /* 相当于int *p=&a[0] */
若有 int a[10];
int *p=a; 则 p+1:指向下一个数组元素。
…
p+i:其指向下移i个元素。
20
说明:若有 int a[10]; int *p=a; (1) p+i *(p+i) = &a[i] a[i]= a+i *(a+i) (2)数组的指针变量也可带下标 a[i] ,p[i], *(a+i),*(p+i) 是等价的。 (3)a与p的区别:a代表数组a的首地址,是常量。 p=a; p也代表数组a的首地址,是变量。 如:p++; 是正确的,而 a++; 是错误的。 (4)引用数组元素有三种方法: 下标法: a[i]或p[i] 地址法:*(a+i) 效率低 指针法:*(p+i) *p++ 效率高
13
讨论: 若将被调函数swap( )改为: swap(int *p1,int *p2) {int *p; *p=*p1; *p1=*p2; *p2=*p; /*中间变量是指针变量所指的对象*/ } p无确定的地址(地址是随机的),可能指向任何单 元,有可能破坏系统(乱放枪)。加上int c;p=&c;就没 有问题了。
3 6 9 …
i j k
2004
3010
2000
i_pointer
3
二.对内存单位的访问 存数—写 取数—读 对内存单位的访问,是通过地址进行的。 如: printf(“%d”,i); 读 再如:scanf(“%d”,&i); 写 直接访问:按变量的地址直接读写变量的值。 如:k=i+j; (1)从2000开始的内存单元中取出i的值3. (2)从2002开始的内存单元中取出j的值6. (3)相加后,送入2004开始的内存单元。 间接访问:将变量a的地址存入另一变量b中,访问a时,先 找b,取出a的地址,再按此地址访问a。
《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)
第10章 常用仪器仪表介绍
13.耦合方式(AC GND DC) 作用于CH2,功能同控件6。 14.通道2输入插座 垂直通道2的输入端口。在X-Y方式时,作为Y轴输入口。 15.垂直位移(POSITION) 用以调节光迹在垂直方向的位置。
电子5
16.通道2灵敏度选择开关 功能同8。 17.微调 功能同9。 18.通道2扩展(×5) 功能同10。
3.直流电阻测量
电子5
装上电池,转动开关至所需测量的电阻档,红、黑表笔分别插入 “+”、“-”插座中,将红、黑表笔两端短接,如果指针不指在欧 姆档零位上需要调整欧姆调零旋钮直到指针对准欧姆“0”位上, 指针指到欧姆零位上为止,如图10-3所示。然后分开红、黑表笔进 行测试。
电子5
电子5
图10-3 MF47型万用表调零方法 a)调零之前 b)调零之后
流放大系数刻度线 4—电容测量刻度线
电子5
5—电感测量刻度线 6—音频测量刻度线
10.1.2 MF47型万用表的使用方法
使用前应检查表的指针是否指示在机械零位上,如果不指示 在零位上,可旋转表盖上的调零器使指针指示在零位上。例 如测量交直流2500V或直流5A时,红插头则应分别插到标有 “2500V”或“5A”的插座中。
电子5
旋足时为校准位置,此时可根据“VOLTS/DIV”开关度盘位置和 屏幕显示幅度读取该信号的电压值。 10.通道扩展开关(PULL×5) 按下此开关,增益扩展5倍。 11.垂直位移(POSITION) 用以调节光迹在垂直方向的位置。
电子5
12.垂直方式(MODE)
选择垂直系统的工作方式。CH1:只显示CH1通道的信号。CH2: 只显示CH2通道的信号。交替:用于同时观察两路信号,此时两路 信号交替显示,该方式适合于在扫描速率较快时使用。断续:两路 信号断续工作,适合于在扫描速率较慢时同时观察两路信号。叠 加:用于显示两路信号相加的结果,当CH2极性开关被按下时,则两 信号相减。CH2反相:此键未按下时,CH2的信号为常态显示。按 下此键时,CH2的信号被反相。
c语言第10章指针
3.间接引用指针
间接引用指针时,可获得由该指针变量所指向的变量内容。
例如,int i=10,*ip=&i;
ip
i
cout<<*ip<<endl;
0000:F384 0000:F384 210
运行结果为:10 即指针ip所指向的变量i的内容。
*放在定义过的指针变量之前,称为间接引用操作符; *放在指针变量定义中时,称为指针定义符。 非指针变量不能用间接引用操作符,*只能作用于地址。
例如, double d=1.23,*dp; char c,*cp;
在&和cp*=作&d用; 下,对变量d和dp有如下6种操作: 其d,中d,dpp,=*&d*是cd; ,非*法dp的,;&&d指,dp针&是只d指p能。针指的向地与址其即同二类级型指的针量。 另外,指针除了可指向所有基本类型的变量外,指针也可 指向常量、数组、数组元素、函数、指针以及文件等。
int ii=n1t0;b, a[10]; int *inpt=&*pi;1,//*初p2始; 化为整型变量的地址,但 *ip=p&1=i;&//是b;错误的
注意:p2不=p要1将; “//可in以t *将ip=一&个i;”已与赋“值*i的p=指&i针;”混赋淆给。另一个相同类型的指针 前者是p2定=&义a语[5句];,*是指针定义符,系统为指针变量ip分配一个空间, 并2、用i数的地组址的值地初址始值化;可后用者该是数执组行语的句数,组左名右表两边示类。型例不如匹:配。 指 例3、针如变,ip函n=d*d量t数bodob;up在u的b=b[3使ll6ee].地8[用*d;4d=址]前/p2,/!(;.,*5值;p一)由[定4该]要; 函被数$赋$$以的d$:p一$名$个$字$地来址表值$$$,示$:否$。$$则$例是如很#6某#:危.#8变险量的。 没有被do赋ub值le的s指in针(d变ou量bdlep的x值);是一个随机地址,把6.8赋给内存中的 随机位do置ub,le很(可*p能f)破( 坏); 了另一个变量,甚至修改了栈中的函数返回 地址,pf造=s成in计; 算机死机或进入死循环。
C语言程序设计第10章文件及其应用
学一学
1.定义文件指针 一般形式为: FILE * fp; 其中fp就是所定义文件指针。 FILE类型 以及所有的文件读写函数和相关常量都定 义在文件stdio.h中,在源程序的开头要 包含头文件 stdio.h 。
学一学
2.打开文件 C语言中,使用fopen函数来打开文件。打开文件是使 一个文件指针变量指向被打开文件的结构变量,以便通 过该指针变量访问打开的文件。fopen函数的调用形式 如下: fopen(chFileName,mode); 以mode 方式打开文件chFileName。其中,参数 chFileName 是将要读写文件的文件名,mode为文件 的操作方式。若文件打开成功,返回一个文件指针,若 打开失败,则返回空值NULL,NULL在stdio.h中被定 义为0。文件操作方式mode是一个整数,其取值及含 义如表10-1所示。
流程图
开始 定义文件指针fp,定义整型数组 iArray[5],定义循环变量i 以写二进制文件方式打开文件 fp=fopen("test.dat","wb") N i=0
fp==NULL Y
i<5 Y 输入1个整数存入 数组元素iArray[i]
N
i++
把数组iArray中5 个整数写入文件
显示出错信息 关闭文件 exit(0)
试一试
问题10.1编一程序从键盘输入一串字符“may friendship forever! ”,然后保存在文件myInfo.txt中。 【解题步骤】 1.定义文件指针fp; 2.定义字符数组chInfo用来存输入的字符串; 3.以写文本文件方式打开文件myInfo.txt; 4.如果打开文件失败,则输出错误信息并结束程序; 5.否则,打开文件成功,则从键盘输入数据; 5.将字符数组chInfo中的字符写入文件myInfo.txt; 6.关闭文件。
第十章 指针(含答案)
第十章指针一、选择题1.以下程序的运行结果是【C】。
sub(int x,int y,int *z){*z=y-x ;}main(){ int a, b,c;sub(10,5,&a);sub(7,a,&b);sub(a,b,&c);printf(”%4d,%4d,%4d\n”,a,b,c);}A. 5,2,3 B. -5,-12,-7 C.-5,-12,-17 D. 5,-2,-72.若已定义 char s[10]; 则在下面表达式中不表示s[1]的地址的是【 B 】A)s+1 B)s++ C)&s[0]+1 D)&s[1]3.下列程序能对两个整型变量的值进行交换。
以下正确的说法是【 D】。
main(){ int a=10,b=20;printf("(1)a=%d,b=%d\n",a,b);swap(&a,&b);printf(“(2)a=%d,b=%d\n”a,b);}swap(int p, int q){ int t; t=p;p=q;q=t;}A. 该程序完全正确B. 该程序有错,只要将语句swap(&a,&b);中的参数改为a,b即可C. 该程序有错,只要将swap()函数中的形参p和q以及t均定义为指针(执行语句不变)即可D. 以上说法都不正确4.有四组对指针变量进行操作的语句,以下判断正确的选项是【】。
(1)int *p,*q; q=p;int a,*p,*q;p=q=&a;(2)int a,*p,*q; q=&a; p=*q;int a=20, *p; *p=a;(3)int a=b=0,* p; p=&a; b=* p;int a=20,*p,*q=&a; *p=*q;(4)int a=20,*p,*q=&a; p=q;int p, *q; q=&p;A.正确:(1);不正确:(2),(3),(4)B.正确:(l),(4);不正确:(2),(3)C.正确:(3);不正确:(1),(2),(4)D.以上结论都不正确5.以下程序中调用scanf函数给变量a输入数值的方法是错误的,其错误原因是【】。
C语言全国计算机二级等级考试教程第10章 字符串(章节带习题)
输出时直到遇第一 char str[ ]=“I love you!” , *p=str; 个‘\0‟结束输出。 字符指针变量 printf(“%s\n” , p); 字符数组名
输入项 字符指针变量
转去介绍
10.3 字符串的输入和输出
字符数组名
输入项
字符指针变量 当字符数组名作为输入项: char str[15]; scanf(“%s”,str); 在内存中的形式是: P R 输入形式为: PROGRAMMING<CR> O G R A M M I N Ga赋初值后的存储示意图
10.4 字符串数组
可以定义字符型指针数组并通过赋初值来构成一个类似的字符串数组。 例如:char *pa[3]={“a”, ”bb”, ”ccc”}; 定义了一个字符型指针数组,该数组中含有3个元素pa[0] 、pa[1]、 pa[2],且每一个 元素都是一个指向字符串的指针。
则在str中存入的只是字符串“APROGRAM”,而不是字符串“APROGRAM MING
10.3 字符串的输入和输出
10.3.3 调用gets、puts函数在终端输入或输出一行字符串
调用gets函数来输入字符串,例如: char str[15]; gets( str ); 在内存中的形式是: A P 若从键盘上依次输入: APROGRAM MING<CR> R O G R A M M I N G \0 \0
★ 两个字符串分别占有不同的存储空间。 ★ 指针变量pmark中的地址可以改变而指向另外一个长度 不同的字符串。
10.3 字符串的输入和输出
10.3.1 输入和输出字符串时的必要条件
输入和输出的格式说明符为 %s 对字符串输入输出时的必要条件: 字符串常量 输出项 字符数组名 printf(“%s\n” , ”I love you!”); char str[ ]=“I love you!”; printf(“%s\n” , str); I love you!
指 针
2. 一维数组元素的地址表示法
由于数组名(设为a)为数组的首地址常量, 用它组成的地址表达式可以表示所有元素的地址, 用这些地址(指针)的指向操作表达式即可表示所 有元素: 元素的地址 元素 a≡&a[0] *a≡a[0] a+1≡&a[1] *(a+1)≡a[1] … … a+i≡&a[i] *(a+i)≡a[i] … … 在表示元素的两种方法中,a[i]为下标法,*(a+i) 为地址法
(3) 通过标准函数获得地址值 (4) 给指针变量赋“空”值,如:p=NULL ;
8.1.3 指针的运算及引用
2.指向运算和指针变量的引用 (1) 指向运算符* *运算符作用在指针(地址)上,代表该指针所指向的存储 单元(及其值),实现间接访问,因此又叫“间接访问运算 符”。如: int a=5, *p; p=&a;printf("%d",*p); *P的值为5,与a等价。*运算符为单目运算符,与其他的单 目运算符具有相同的优先级和结合性(右结合性)。根据*运 算符的作用,*运算符和取地址运算符 & 互逆: *(&a)==a &(*p)==p (2) 指针变量的引用 知道了指针变量的作用以及相关的运算符以后,我们就可 以引用指针变量了
8.1.4 指针作为函数参数
被调函数中的形参:指针变量 主调函数中的实参:地址表达式,一般为变 量的地址或取得变量地址的指针变量 例8-3同例8-2,要求用函数调用交换变量的值。
swap(int *p1, int *p2) { int t; t=*p1; *p1=*p2; *p2=t; } main() { int i1, i2; printf("Enter two numbers:\n"); scanf("%d%d", &i1, &i2); if(i1<i2) swap(&i1, &i2); printf("i1=%d,i2=%d\n",i1, i2); }
