第8章c语言指针
C语言 第八章
p
printf(“%d,%d\n”,a,b); printf(“%d,%d\n”,*p1,*p2);}
三、指针变量作为函数参数 作用:将一个变量的地址传送到另一个函数中。 作用:将一个变量的地址传送到另一个函数中。 例1:编写实现两个数的交换的函数 : swap(int *p1, int *p2) *p2) void swap(int *p1, int swap(int x,int y) {{ int temp; 定义为*temp? ? int temp; 定义为 { int temp; temp=*p1; temp=x; temp=*p1; *p1=*p2; x=y; *p1=*p2; y=temp; } *p2=temp; } *p2=temp; } main() main() main() { int a,b,*p1,*p2; { int a,b; { int a,b p1=&a;p2=&b; scanf("%d,%d",&a,&b); scanf(“%d%d”,&a,&b); scanf(“%d%d”,p1,p2); swap(a,b); swap(&a,&b); swap(p1,p2); printf("\n%d,%d\n",a,b); printf("%d, %d\n",a,b); printf("%d, %d\n",a,b); }} }
个字节的问题) 个字节的问题)
二、指针变量的引用 “&”(地址运算符 取变量的存储地址。如:&a求变量 的地址。 地址运算符) 取变量的存储地址。 地址运算符 求变量a的地址 求变量 的地址。 “*” (引用运算符 取指针所指向变量的内容。&与*优先级相同, 引用运算符) 取指针所指向变量的内容。 与 优先级相同 引用运算符 优先级相同, 但按自右至左的结合方向。 但按自右至左的结合方向。 例如: 例如:int i=3,*p; p=&i;
《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章 指针结构体与预处理命令
指针使用示例 2 void main() { int num1 = 50, num2 = 100; int *ptr1, *ptr2; ptr1 = &num1; printf(" num1 的值是: %d", *ptr1); printf("\n num1 的地址是: %x \n", ptr1); ptr2 = &num2; printf("\n num2 的值是: %d", *ptr2); printf("\n num2 的地址是: %x \n", ptr2); *ptr2 = *ptr1; printf("\n 重新赋值后 num2 的值是: %d", *ptr2); printf("\n 重新赋值后 num2 的地址是: %x\n", ptr2); }
C 语言程序设计知识点
主讲教师:杨剑
第 8 章:指针、结构体与预处理命令
1. 本章目标
理解指针的概念 定义指针变量 掌握对指针的操作 理解指针和数组的关系 理解结构体的概念和定义 理解预处理指令
2. 内存地址
内存是一个连续编址的空间,每一个存储单元都有一个固定的编号,称为内存地址。 内存地址通常用 16 进制数表示。
C语言0指针
8.2指针变量的定义与引用
注: 1.用变量的地址给指针变量赋值(求地址运算符&) 2.用相同类型的指针变量赋值 3.若不赋值,则指针变量的值是随机的。赋空值 NULL 如:p=NULL;或p=0; 4.变量的类型必须与指针变量的类型相同
首页
上页
下页
返回
8.2指针变量的定义与引用
三、指针变量的应用 int a; 1.两个有关的运算符 int *p; 形式:&任意变量 /*取地址运算符*/ p=&a; *指针变量 /*指针运算符*/
含义:&a表示变量a所占据的内存空间的首地址 *p表示指针变量p所指向的内存中的数据
首页
上页
下页
返回
例题讲解
void main() {int a=5,b=3; int *p; p=&a; b=*p+5; printf("%d\n",b); *p=4; printf("%d,%d\n",a,*p); }
二、变量的访问方式 1、直接访问
int a;
3AB0
3 a
3AB8 5
float b;
a=3; b=5;
b
将3送入变量a所占据的 内存单元(地址3AB0)
首页 上页 下页 返回
8.1指针的概念
2、间接访问 定义一个变量p,存放a的地址,通过p访问a 若将变量p的值改为3AB8(b的地址),则可 通过p访问b 3AB0 3AB8
在C语言中,将地址形象化地称为指针
3AB0 3 a 3AB8 5 b 3AB0 p
首页 上页 下页 返回
指针说明符
8.2指针变量的定义与引用
C语言程序设计第8单元
二维数组的地址
【例8.9】使用指针变量输出二维数组元素 #include<stdio.h> main() { int a[2][3]={{1,2,3},{4,5,6}},*p;
for(p=a[0];p<a[0]+6;p++) { if((p-a[0])%3==0)printf("\n");
printf("%2d",*p); } }
0x62fe3a
0x62fe3b
0x62fe3c
数组指针的运算
对于指针变量p,可以做以下运算: p++,p--,p+i, p-i, p+=i, p-= i等。
#include <stdio.h> main() { int a[]={1,3,6,7,9,12};
int x,*p=&a[2]; x=(*--p)++; printf("x=%d\n",x); printf("a[1]=%d\n",a[1]); }
0x62fe50
二维数组的地址
#include <stdio.h>
main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,a1是1,1行2指}};针
printf("%x,%x,%x\n",a,a+1,a+2); printf("%x,%x,%x\n",*a,*(a+1),*(a+2)); *a是列指针
二维数组的地址
二维数组名是数组的首地址,二维数组名的基类型不是数组元素类 型,而是一维数组类型,因此,二维数组名a是一个行指针。
高树芳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语言第8章练习题--指针
1、int *p 的含义是(B)A.p是一个指针, 用来存放一个整型数B.p是一个指针, 用来存放一个整型数据在内存中的地址C.p是一个整型变量D. 以上都不对2、以下函数用来求出两整数之和,并通过形参将结果传回,请填空。
void func(int x,int y, ___int*____ z){ *z=x+y; }3、有如下程序段(B)int *p,a=10,b=1;p=&a; a=*p + b;执行该程序段后,a的值是A. 12B. 11C. 10D. 编译出错4、若己定义:int a[9],*p=a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是( C)A) p+1B) a+1C) a++D) ++p5、以下程序运行后的输出结果是(A)void main( ){ int a[ ]={1,2,3,4,5,6,7,8,9,0},*p;for(p=a;p<a+10;p++) printf("%d,",*p);}A)1,2,3,4,5,6,7,8,9,0,B)2,3,4,5,6,7,8,9,10,1,C)0,1,2,3,4,5,6,7,8,9,D)1,1,1,1,1,1,1,1,1,1,6、下面程序的输出是(D)void prtv(int *x)printf("%d\n", ++*x);}main(){ int a=25;prtv(&a);}A) 23 B) 24 C) 25D) 267、有以下函数(B)char fun(char *p){ return p; }该函数的返回值是A) 无确切的值B) 形参p中存放的地址值C) 一个临时存储单元的地址D) 形参p自身的地址值8、下列程序的输出结果是(7)#include<stdio.h>void fun (int *p1, int *p2){ if (*p1>*p2) printf ("%d\n",*p1);else printf ("%d\n",*p2);}void main ( ){ int a=3,b=7;fun (&a, &b);}9、下列程序的运行结果是(B)void fun(int *a, int *b){ int *k;k=a; a=b; b=k;}main(){ int a=3, b=6, *x=&a, *y=&b;fun(x,y);printf("%d %d", a, b);}A) 6 3 B) 3 6 C) 编译出错D) 0 010、以下程序调用findmax函数返回数组中的最大值(B)findmax(int *a,int n){ int *p,*s;for(p=a,s=a; p-a<n; p++)if ( ) s=p;return(*s);}main(){ int x[5]={12,21,13,6,18};printf("%d\n",findmax(x,5));}在下划线处应填入的是(B)A) p>s B) *p>*s C) a[p]>a[s] D) p-a>p-s11、下列程序段的输出结果是(A)void fun(int *x, int *y){ printf("%d %d", *x, *y); *x=3; *y=4;}main(){ int x=1,y=2;fun(&y,&x);printf("%d %d",x, y);}A) 2 1 4 3 B) 2 1 3 4 C) 1 2 1 2 D) 2 1 1 212、以下程序执行后输出的结果是___84________。
C语言程序设计第八章 优化学生成绩分析系统指针.ppt
C语言程序设计
1 指针与字符串(5)
1.2 使用字符串指针变量与字符数组的区别(续) 例2 分析下面程序的运行结果
main() { char *a="I Love China!";
a=a+7; printf(“%s\n",a); }
运行结果: China!
9
项目八 优化学生成绩分析系统-指针
C语言程序设计
int a,b,c;
例sc6an将f(给"%出d的,%程d"序,&修a,改&b为);使用函数指针变量定义
的c=方m式ax(a,b);
c=(*p)(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
}
max(int x,int y)
{
int z;
if(x>y) z=x;
else z=y;
指针数组,有4个元素,每个元素 都是指向整型变量指针变量
Int (*p)[4];
由4个整型变量组成的数组的指针
21
项目八 优化学生成绩分析系统-指针
#include <stdio.h> ma3in指()针数组 (2)
C语言程序设计
p[0]
11
{ 3.1 指针数组(续)
22
static int
33
a[3][4]={{11,22,33,44},{55,66,77,88},{99,110,1224,4133}};
【项目分析】
为了保存一个班的C语言成绩需要借助于一维数组,通过指针对其数 据进行操作。将本项目分成两部分,首先借助于指针对一维数组进 行访问,然后介绍一种新的排序算法—选择排序。
第8章 指针-3字符数组和字符指针 - 字符串的输入和输出
第8章 指针
用scanf输入/输出字符串
#include <stdio.h> #define STR_LEN 80 int main() { char str[STR_LEN+1], ch; printf("Input a string:"); scanf("%s", str); printf("%s\n", str); printf("Input a character:"); getchar(); scanf(" "); ch = getchar(); printf("%c\n", ch); return 0; }
C语言程序设计
第8章 指针
讨论
见证奇迹的时刻——Mission Impossible
源程序(不要添加任何空格和换行) main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}";printf(a,3 4,a,34);} 运行结果与源代码完全一样,你能解释这个运行结果吗? main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}"; printf(a,34,a,34);}
C语言程序设计
gets()将回车从缓冲区读走,但不 作为字符串的一部分,用空字符代替
第8章 指针
用gets输入/输出字符串
#include <stdio.h> #define STR_LEN 80 int main() { char str[STR_LEN+1], ch; printf("Input a string:"); gets(str); printf("%s\n", str); printf("Input a character:"); ch = getchar(); printf("%c\n", ch); return 0; }
C语言程序设计(第八章)
的读写函数。 每次可从文件读出或向文件写入一个字符。
第八章
1.读字符函数fgetc()
fgetc() 函数的功能是从指定的文件中读一个字符,函
数调用的形式为:
字符变量 = fgetc(文件指针);
例如:
ch = fgetc(fp);
的意义是从打开的文件fp中读取一个字符并送入ch中 。
(1)字符读/写函数 :fgetc()/fputc()
(2)字符串读/写函数:fgets()/fputs()
(3)数据块读/写函数:freed/()fwrite()
(4)格式化读/写函数:fscanf()/fprinf()
以上函数原型都在头文件stdio.h中加以声明。
第八章
8.5.1字符读/写函数 :fgetc()/fputc()
关闭文件则断开指针与文件之间的联系,禁止再对该文
件进行操作。
第八章
8.3.1 文件打开的函数fopen()
open函数用于打开一个文件,其调用的一般形式为: 文件指针名 = fopen(文件名, 使用文件方式);
“文件指针名”:必须是被说明为FILE 类型的指针变量。
“文件名”:被打开文件的文件名,“文件名”是字符串常 量、字符数组或字符指针。 “使用文件方式”:指文件的类型和操作要求。
/* 输出系统提示信息 */
上面程序段的意义是,如果返回的指针为空,表示不能 打开test.dat文件,则给出提示信息“打开文件test.dat出 错!”,然后输出系统提示信息,当用户从键盘敲任一键后 执行exit(1)退出程序 。
第八章
8.3.2 文件关闭的函数fclose()
第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章 指针
例8-13 求最长字符串。
函数的返回值为指针,指针数组作函数参数。
8.5.2 执行函数的指针变量(P207)
P207 自学
8.6 指针应用举例 (P208)
P208 自学
8.7 动态内存管理 (P214)
动态分配存储空间
malloc( )函数 calloc( ) 函数
2. 变量地址示意图
变量 b 的地址:XXXX 变量b 4字节
例: float b; char c;
变量 c 的地址:XXXX 数组 a 的地址:XXXX
变量c 1字节
int a[2];
数组a 8字节
变量的地址示意图
8.1.1 指针和指针变量(P185)
指针
变量的存储地址称为该变量的指针。
指针变量
for (i=0;i<4;i++)
p[i]=&a[i*3]; printf ("%d\n",p[3][2]);
8.4 指针作为函数的参数 (P199)
指针变量 ① 形参是指针变量,对应实参是 变量地址 数组名 指针变量 ② 形参是数组名,对应实参是 变量的地址 数组名
8.4.1 指针作参数示例
例8-10 两数交换。形参为指针变量,实参为变量
char *p="abcd";
读下列程序段,分析输出结果
(1)
char s[]="ABCD";
char *p; for (p=s; p<s+4; p++) printf("%s\n",p);
读下列程序段,分析输出结果
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语言程序设计(第二版)-电子教案-丁亚涛-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语言中如何使用指针。
学习要点包括如下几点:(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语言指针
#include <stdio.h>
void main()
{ int a=5,b=3;
int *p;
10
p=&a;
4,4
b=*p+5;
printf(“%d\n”,b);
*p=4;
printf(“%d,%d”,a,*p);
}
三、数组的指针与函数实参
例:编写一函数求一维数组的最大元素及其下 标位置(要求使用指针) 已知:数组首地址p,元素个数n;(作函数参 数) 结果:下标k;(作返回值) int max_array(int *p,int n) 设最大值放在max中,则初始状态为:
max=*p, k=0 如果*(p+i)>max 则max=*(p+i)且k=i
a[i] &a[i][0] *(a+i)
数组元素地址
a+i &a[i]
不要把&a[i]理解为a[i]单元的物理地址,因为 a[i]不是一个变量, &a[i] 和a[i]的值是相等的。但 含意不一样。前者指向行,后者指向列; &a[i]:第i行的首地址 a[i]:第i行0列地址 &a[i]+1:第i+1行的首地址 a[i]+1:第i行1列的地址
指针变量作函数参数
例:编写一个函数实现两个数的交换。
#include<stdio.h>
#include<stdio.h>
void swap(int x,int y) void swap(int *x,int *y)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例
通过指针改变变量的值 通过指针改变变量的值 指针改变
p1 &a p2 &b a 2 1 b 1 2 *p1 *p2
# include <stdio.h> int main (void) { int a = 1, b = 2, t; int *p1, *p2;
p1 = &a; p2 = &b; printf ("a=%d, b=%d, *p1=%d, *p2=%d\n", a, b, *p1, *p2); t = *p1; *p1 = *p2; * p2 = t; printf ("a=%d, b=%d, *p1=%d, *p2=%d\n", a, b, *p1, *p2); return 0; a = 1, b = 2, *p1 = 1, *p2 = 2 } a = 2, b = 1, *p1 = 2, *p2 = 1
2、移动指针(指针与整数相加、减): 、移动指针 指针与整数相加 指针与整数相加、 : 表示指针在内存空间的上下移动。 ※ 表示指针在内存空间的上下移动。 ※ 移动是以其类型长度为单位的 。 a[0] a[1] a[2] a[3] a[4] 11 22 33 q↑ 44 q↑ 55
p↑ p↑ q=p+2 = + y=*q++ ++p y=* --p
指针变量的定义
类型名 * 指针变量名 int * p; 指针变量名是 p,不是 ,不是*p * 是指针声明符 意为该变量是指针型变量 是指针声明符, 指针变量具有确定指向的数据类型, 指针变量具有确定指向的数据类型 必须区分 基类型。 基类型。 指针变量和一般变量可一起定义 指针变量和 int k, *p1, *p2; 等价于: 等价于: int k; int *p1; int *p2;
*p
2、* 间接访问运算符,访问指针所指向的变量 、 间接访问运算符, *p:指针变量 p 所指向的变量 指向的变量 :
例 指针取地址运算和间接访问运算
# include <stdio.h> p int main (void) { int a = 3, *p; &a p = &a; printf (“a=%d, *p=%d\n”, a, *p); *p = 10; printf("a=%d, *p=%d\n", a, *p); printf("Enter a: "); scanf("%d", &a); printf("a=%d, *p=%d\n", a, *p); (*p)++; printf("a=%d, *p=%d\n", a, *p); return 0; }
8.1 问题的提出
一个关于特工008寻找保险箱密码的故事… 一个关于特工008寻找保险箱密码的故事 008寻找保险箱密码的故事 关键点分析 得到线索:0217单元的 虎跑号” 单元的“ 得到线索:0217单元的“虎跑号”寄存箱 提示地址:1976单元 提示地址:1976单元 找到目标: 龙井号” 找到目标:“龙井号”寄存箱 取出内容: 取出内容:911
例8-5 指针变量 变量的 指针变量的初始化 int main (void ) a = 1, b = 2, *p1 = 1, *p2 = 2 { int a=1, b=2; a = 1, b = 2, *p1 = 2, *p2 = 1 int *p1 = &a, *p2 = &b, *pt; printf ("a=%d, b=%d, *p1=%d, *p2=%d\n", a, b, *p1, *p2); pt = p1; p1 = p2; p2 = pt; printf (“a=%d, b=%d, *p1=%d, *p2=%d\n”, a, b, *p1, *p2); return 0; } p1 a p1 a *p2 &b 1 *p1 &a 1 p2 b p2 b *p1 &a 2 *p2 &b 2 pt pt &a
a 3
*p
a = 3, *p = 3 a = 10, *p = 10 Enter a: 5 a = 5, *p = 5 a = 6, *p = 6
TC IDE
关于运算符&和 的几点说明: 关于运算符 和 * 的几点说明: (1)结合性:自右向左 )结合性: &*p1 相当于 &(*p1) ==&(a)==&a==p1 *&a 相当于 *(&a)==a (2)优先级:高于算术运算符。 )优先级:高于算术运算符。 单目运算符都为次高级(2级 运算符都为次高级 单目运算符都为次高级 级)
第8章 指针
本章要点
变量、内存单元和地址之间是什么关系? 变量、内存单元和地址之间是什么关系? 如何定义指针变量,怎样才能使用指针变量? 如何定义指针变量,怎样才能使用指针变量? 什么是指针变量的初始化? 什么是指针变量的初始化? 指针变量的基本运算有哪些? 指针变量的基本运算有哪些?如何使用指针 操作所指向的变量? 操作所指向的变量? 指针作为函数参数的作用是什么? 指针作为函数参数的作用是什么? 如何使用指针实现函数调用返回多个值? 如何使用指针实现函数调用返回多个值? 如何利用指针实现内存的动态分配? 如何利用指针实现内存的动态分配?
TC IDE
8.5
指针与函数 指针与函数
一、指针作为函数参数: 指针作为函数参数: 1、用指针(地址)作函数参数,可以实现 、用指针(地址)作函数参数, “通过被调用的函数改变主调函数中变量的值 的目的。 ”的目的。 2、使用指针作为函数参数可以在调用一个 、 函数时得到多个由被调函数改变了的值。 函数时得到多个由被调函数改变了的值。
对指针的操作 / 对指针所指向变量的操作
*p1 和 *p2 的值由 1 和 2 变成了 2 和 1 (1) 直接改变指针的值 (2) 改变指针所指变量的值
p1 &a p2 &b p1 &b p2 &a b 2 *p1 a 1 *p2 p2 &b p1 &a b 1 *p2 b 2 *p2 a 2 *p1 a 1 *p1
取地址运算和间接访问运算
如何使指针的值是某个变量的地址和通过指针就能间 如何使指针的值是某个变量的地址和通过指针就能间 接访问那个变量 那个变量? 接访问那个变量 1、& 取地址运算符,给出变量的地址 、 取地址运算符, int *p, a = 3; p = &a; 指针变量的类型和它所指向变量的类型相同 把 a 的地址赋给 p,即 p 指向 a , p &a a 3
寻找密码的途径分析
密码911存放在某个寄存箱内, 密码911存放在某个寄存箱内,如果我们 911存放在某个寄存箱内 知道这个寄存箱的名字, 知道这个寄存箱的名字,就能够找到密码 如果不知道密码所在的寄存箱名字, 如果不知道密码所在的寄存箱名字,知道 该寄存箱的地址也照样能够取出密码 如果寄存箱的地址也不知道, 如果寄存箱的地址也不知道,但是有另外 一个地方存放这个寄存箱的地址, 一个地方存放这个寄存箱的地址,就能顺 藤摸瓜, 藤摸瓜,间接找到密码
8.2
指针与指针变量 指针与指针变量 指针
变量名与变量值的关系
内存的访问方式
内存单元 地址 内容
1000 1002 1004 20 1 155
变量 直接访问: 直接访问:通过变量名访问
x y z
int x = 20, y = 1, z = 155; printf("%d", x;) 间接访问:通过另一个变量访问 间接访问:通过另一个变量访问
给指针变量赋“空”值 给指针变量赋“ p1=NULL; 说明: 说明: 中的预定义符, (1)NULL是stdio.h中的预定义符,用到 ) 是 中的预定义符 NULL需加命令:#include “stdio.h” 需加命令: 需加命令 的值为0, (2)NULL的值为 ,即“空”。 ) 的值为 (3)p1=NULL ; 等价于 p1=‘\0’; 或 ) p1=0;
2000 2002
1000
p
地址
指针变量
指针变量的定义: 指针变量的定义 类型名 * 指针变量名
指针变量所指向的变量的类型 指针声明符
int *p;
p 是整型指针,指向整型变量 是整型指针,
float *fp;
fp 是浮点型指针,指向浮点型变量 是浮点型指针,
char *cp;
cp 是字符型指针,指向字符型变量 是字符型指针,
p1 &c &a p2 &b &a
a 2 b 4 *p2 *p1 *p2
a = 2; b = 4; c = 6; c p1 = &a; p2 = &b; 6 *p1 printf ("a=%d, b=%d, c=%d, *p1=%d, *p2=%d\n", a, b, c, *p1, *p2); a = 2; b = 4; c = 6; *p1 = 2, *p2 = 4 p2 = p1; p1 = &c; printf ("a=%d, b=%d, c=%d, *p1=%d, *p2=%d\n", a, b, c, *p1, *p2); a = 2; b = 4; c = 6; *p1 = 6, *p2 = 2 return 0; }
密码存放示意图
虎跑号 龙井号
1976
0217 名字 地址 内容 虎跑号 0217 1976
911
1976 龙井号 1976 911
利用指针模拟寻找保险箱密码的过程
获取密码的两种方法 int main(void) { int key = 911; /* 变量 变量key存放密码 */ 存放密码 int *addr = NULL; /* 变量 变量addr存放地址 */ 存放地址 addr = &key; /* 将key的地址赋给addr */ key的地址赋给 的地址赋给addr /* 通过变量 通过变量key输出密码值 输出密码值*/ 输出密码值 printf("The key is: %d\n", key); /* 通过变量 通过变量key的地址来输出密码值 */ 的地址来输出密码值 printf("If I know the address of the key, I also *addr); can get it: %d\n",The key is: 911 return 0; If I know the address of the key, I also can get it: 911 }