第1讲 指针(1)

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

(4)什么是指针?
概念:指针是一个特定类型数据的存储地址,比如一个变量的 地址 a 如:int a=100; 指针 0x0012FF7C
100
说明: 指针也是一种数据类型,占4个字节; 用户定义的对象必须由系统分配存储空间; 空指针值:即NULL,它不指指向任何地方,在VC定义为 常数0,任何类型的指针变量都可以赋予该值。
C
h
I n a ‘\0‟
6bytes
由此可见,数据单元在内存中是连续存放的,根据其首地址 和数据类型,就能确定其所占用的存储单元个数和数据存储方 式,实现存取数据的目的。
(3)两种存取变量的方式
直接存取方式:按变量名存取 在程序中定义的变量编译时系统为其 这些操作由编译系统、 分配内存单元,以下列代码为例进行说明: 操作系统自动完成, 用户不用考虑。 int data1=3456; data1 3456 printf(“%d”, data1);
说明: 一条语句中定义多个变量,每一个指针变量前的*号不能省 略,例如:int *p_a, *p_b; 指针变量的赋值=: 赋值号两边的指针类型必须相同; 其它指针的值可以赋值给空类型指针,反过来不允许; 不同类型指针变量赋值时,要进行强制转换。 指出下列代码中的错误: p未指向有效地址,是悬空指针; int *p,a=1; float *q; q指向的变量数据类型与指针变量 *p=5; 定义的数据类型不一致。 q=&a; printf("p的地址:%X,p的值:%d\n",p,*p); printf("q的地址:%X,q的值:%f\n",q,*q);
(3) 指针变量作为函数参数
例3: 题目要求同例 2,即对输入的两个整数按大小顺序输出。 现用函数处理,而且用指针类型的数据作函数参数。 解题思路:定义一个函数swap,将指向两个整型变量的指 针变量作为实参传递给swap函数的形参指针变量,在函数 中通过指针实现交换两个变量的值。
#include <stdio.h> int main() { void swap(int *p1,int *p2); int a,b; int *pointer_1,*pointer_2; printf("please enter a and b:"); scanf("%d%d",&a,&b); pointer_1=&a; 错!!! pointer_2=&b; 无确定的指向 if(a<b) swap(pointer_1,pointer_2); printf("max=%d, min=%d\n\n",a,b); return 0; } void swap(int *p1,int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; }
2. 指针变量 (1)概念与定义格式
概念:用来存放一个数据(对象)的地址的变量。指针变量的 值是地址(即指针) 定义格式:数据类型 * 变量名 [=指针表达式]; 说明: *是指针类型的标志,不能省略;它不是指针变量名的组成部 分; 数据类型是指针变量中所存地址指向的数据的类型,又称基 类型,它决定了数据占用的存储单元长度及存储方式,不同 数据类型占用的存储单元长度可能不同,即使长度相同,存 储方式也不同;数据类型是通过指针存取数据的基础,不允 许定义无数据类型的指针变量; 允许对指针变量初始化,即定义时并赋地址值。
数据单元
0X0012FF74
0X0012FF75
……
3.14
8bytes
0X0012FF7B
char ch=„A‟;
0x0012FF70
A
1bytes
char str[ ]=“China”;
0x0042901C 0x0042901D 0x0042901E 0x0042901F 0x00429020 0x00429021
源程序
目标代码地址空间
0
内存地址空间
基址 =1000
输出单元200 开始的4B内容
int data1=3456;
printf(“%d”, data1);
100 编译 连接 200
1100
输出单元1200 开始的4B内容
地址ห้องสมุดไป่ตู้射
3456
(“水涨船 高”) 1200
3456
间接存取方式:
p 变量i的地址存放在变量p i 中,通过p来存取i的值, 2000 3345 这种变量的存取方式称为 2000 间接存取方式 指向就是通过地址来体现的,如上例,p中存放了i的地址, 通过p就能知道i的地址,从而找到变量i的内存单元; 由于通过地址能找到所需的变量单元,因此说,地址指向该 变量单元; 将地址形象化地称为“指针”,意思是通过它能找到以它为 地址的内存单元; 一个变量的地址称为该变量的“指针”,专门用来存放另一变 量的地址(即指针)的变量,称为“指针变量”。“指针”与 “指针变量”不同。
问题:能否将swap()写成如下形式?
void swap(int *p1,int *p2) { int *temp; *temp=*p1; 问题:int *temp;与 *p1=*p2; *temp=…;的星号(*) *p2=*temp; } 有什么不同?
思考:以下程序代码能否实现数据的交换?
#include <stdio.h> int main() { …… if (a<b) swap(a,b); printf(“max=%d,min=%d\n”,a,b); return 0; } void swap(int x,int y) { int temp; temp=x; x=y; y=temp; } 普通类型作函数参数时,是 “值传递”方式,函数调用时把 实参复制给形参,在函数内形参 的改变不影响实参。
0X00000000
存储单元,大小为1B 计算机控制器通过存储 单元地址可以存取其中 的内容。 在地址所标识的内存 单元中存放数据,这相 当于旅馆房间中居住的 旅客一样。 由于通过地址能找到 所需的变量单元,我们 可以说,地址指向该变 量单元。 将地址形象化地称为“指针”
0X00000001
0X00000002 0X00000003 ……
如何避免悬空指针的使用?
定义指针变量时坚持对其进行初始化,若不能确定它指 向哪一个变量,则让该指针变量初始化为NULL,例如:
如 int *p = NULL; //正确地进行初始化
空类型与空指针的比较 void: 空类型,即不指明任何具体的数据类型; void * :空类型指针,不指向任何类型,即 void * 指针仅仅为 一个地址; 允许将其它指针的值赋给空类型指针,但不允许将空类型指针赋 给其它指针,除非进行强制转换; NULL与void * 不同:NULL是一个指针值,任何类型的指针可 以赋予该值,而void * 是一种类型,是一种无任何类型的指针; 可以根据实际需要,对指针类型进行强制转换。
⑤主调函数中就可以使用这些改变了值的变量。
不要企图通过改变指针形参的值而使指针实参的值改变。 下面例子并不成功。 例4: 对输入的两个整数按大小顺序输出 解题思路:尝试调用swap函数来实现题目要求。在函数中 改变形参(指针变量)的值,希望能由此改变实参(指针变量) 的值。
#include <stdio.h> int main() { void swap(int *p1,int *p2); int a,b; int*pointer_1,*pointer_2; printf("please enter two integer numbers:"); scanf("%d%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("max=%d,min=%d\n\n",a,b); return 0; }
例2: 输入a和b两个整数,按先大后小的顺序输出a和b。
解题思路:用指针方法来处理这个问题。不交换整型变量的 值,而是交换两个指针变量的值。
#include <stdio.h> int main() { int *p1,*p2,*p,a,b; printf("please enter two integer numbers:"); scanf("%d %d",&a,&b); // 输入两个整数 p1=&a; // 使p1指向变量a p2=&b; // 使p2指向变量b if(a<b) // 如果a<b { p=p1;p1=p2;p2=p; } //p1与p2的值互换 printf("a=%d,b=%d\n",a,b); // 输出a,b printf("max=%d,min=%d\n",*p1,*p2);// 输出p1和p2所指向的变量的值 return 0; }
第1讲 指针(1)
指针的概念 指针变量
教学目标
理解指针的概念和作用;
掌握指针变量的定义、取地址和间接访问运算,能够利用指
针变量作为函数参数、得到n个要改变的值。
重点:指针的概念和作用,指针变量的定义和&、*运算,指针 变量作形参的作用
难点:指针的概念,指针变量的定义和&、*运算,指针变量作
例如:int a=100; int *p_a=&a;
p_a
&a即是 0x0012FF7C
a
100 指向
首地址: 0x0012FF7C
p_str 指向
?
(指针变量未赋值)
问题:为什么指针变量通常用p开头? 指针(pointer)的首字符是p 悬空指针: 如果一个指针变量,既没有赋NULL值,又没有指向有效的 内存地址,则称为“悬空指针”; 悬空指针的值是不确定的,这个未知地址可能指向一个有用 数据或一段代码,直接操作可能带来危险,甚至导致系统崩 溃,应尽力避免悬空指针的使用;
如果想通过函数调用得到n个要改变的值: ① 在主调函数中设n个变量,用n个指针变量指向它们;
② 设计一个函数,有n个指针形参。在这个函数中改变这n个 形参的值;
③ 在主调函数中调用这个函数,在调用时将这n个指针变量作 实参,将它们的地址传给该函数的形参;
如果想通过函数调用得到n个要改变的值:
④ 在执行该函数的过程中,通过形参指针变量,改变它们所指 向的n个变量的值;
(2)指针的两个特殊运算符(单目运算符)
& :取地址运算符,返回其操作对象的内存地址,通常其操 作对象为一个变量,例如 p_a=&a ; * :间接访问运算符,存取指针所指单元的值,如: printf(“%d”, *p_a); 可以输出变量a的值。
//例1:运算符 & 与 * 使用举例: #include <stdio.h> int main() { int a=10; int * p_a; p_a=&a; //取地址 printf(“变量a的地址(十六进制): %X\n",p_a); printf("修改前:直接访问 a=%d, 间接访问 a=%d\n",a,*p_a); *p_a=10000; //通过间接访问,修改a值 printf("修改后:直接访问 a=%d, 间接访问 a=%d\n\n",a,*p_a); return 0; }
形参的作用
1. 指针的概念
指针是C语言的一个重要概念,也是C语言的一个重要特色, 正确而灵活地运用它,可以使程序简洁、紧凑、高效。不掌握 指针就是没有掌握C的精华。 在介绍指针之前,有必要了解内存地址的相关知识。
(1)内存地址
程序必须装载到内存中才能运行,而计算机的内存是一维 线性空间。 假设计算机内存为4GB,则它是由232个存储单元(大小为 1byte)组成,可以将这些存储单元按照从小到大的顺序编址, 都是用二进制表示的,转换为十六进制则对应的地址范围为 0X00000000—0XFFFFFFFF。为直观起见,内存地址常用十 进制数描述。
……
0XFFFFFFFD 0XFFFFFFFE
0XFFFFFFFF
内存线性空间 存储单元地址
(2)不同类型的数据占用内存单元的个数、存储方式不同
0x0012FF7C
int a=100;
0X0012FF7D
0X0012FF7E
100
4bytes
数据单元 首地址
double pi=3.14;
0X0012FF7F
相关文档
最新文档