当前位置:首页 >> 电脑基础知识 >>

C语言重点————指针


计算机程序设计
第八章 指 针

自动化系 王雷

提纲
? 指针的概念
? 指针变量 ? 指针与数组 ? 指针与函数 ? 指针与内存

自动化系 王雷

8.2 指针的概念
程序运行时,代码和数据都要装入内存中(二进制 形式,以字节为基本单位) ? 内存也是以字节为单位编址 ? 不同类型的数据占用的内存空间大小不同,如字符 型1个字节,单精度浮点数4个字节,整型4个字节 等,而且存储形式不同(因此,同样数量字节中的 同样数据,按不同类型读取时意义不同) ? 执行程序时,CPU并不识别变量的名称,而是通过 其地址进行操作 ? 程序一般通过变量名存取变量值(直接访问),但也 可以通过地址操作变量——指针(pointer)间接访问
?
自动化系 王雷

...... 1000H (1004) 0000 0000 0000 0000 0001 0000 0000 0100 1004H (3.14159) 0100 0000 0100 1001 0000 0000 0000 0000 1008H ......

? ?
p x

{ float *p; float x=3.14159; p=&x; ...... }
p为指针变量,其值 为变量x的地址

自动化系 王雷

8.3 指针变量的定义
指针变量也占据内存空间,但指针变量的内容是其 所指变量的地址,因此只有依托其所指向的变量才 有实际应用 ? 指针变量使用指针运算符“*”来定义指向关系,定 义的一般形式:
?

类型 *指针变量名; int *ip; char *next; float *fp;
自动化系 王雷

? 指针变量定义的注意事项
?指针变量定义时注明的类型,是指针所指向变量

的类型 ?定义了指针变量ip后,通过*ip来使用指针所指向 的对象 ?指针变量的取值是其所指向变量的地址,而地址 是内存单元的编号,是带有地址属性的特殊整数 ?不同类型变量不仅占用内存的字节数不同,而且 对内存单元的起始地址也有不同要求,如char要 求奇数地址,int、float、double要求偶数地址 ?使用所指对象的类型来描述指针变量的目的是便 于识别和使用指针所指向地址的内容,特别对于 指针的位移操作具有重要意义
自动化系 王雷

? 关于指针变量的类型
?对于编译系统,指针类型的作用是用来获取所指

数据类型的长度,并以此确定指针单位增量的长 度。即,当对指针进行增减时,实际是希望指针 向后或向前指向保存在同一片存储区域中具有相 同数据类型的其他单元的地址 ?如:float *fp,x[]={1.0, 2.0, 3.0}; fp=&x[1]; 则*fp=2.0, *(fp-1)=1.0, *(fp+1)=3.0 fp每次增减都在内存中向后或向前移动4个字节 并按float类型访问该地址中的数据
自动化系 王雷

? 关于指针变量的类型(续)
?不同类型的指针既不能互相转换,也不能互相赋

值(因不同类型数据在内存中的存放方式不同) 如:int *ip,i; float *fp,f; ip=&i;fp=&f; //合法 ip=&f;fp=&i; //不合法 ?注意,不管指向何种类型的对象,指针变量本身 占用内存的字节数都是一样的,要能够把程序中 所能用的最大地址表示出来(通常是一个机器字 长)
自动化系 王雷

? 指向复杂数据类型的指针

char (*ptr)[5]; //ptr是指向由5个字符元素构成的数组的指 针变量 int **ip; //ip是一个“指向整型量的指针变量”的指针变量 int *fip(); //fip是返回整型指针的函数(函数声明) int (*pti)(); //pti是指向一个返回整数的函数的指针变量 int *(*pfpi)(); //pfpi是一个指向函数的指针变量,该函数返 回指向整数的指针 如何区分函数和指针?看运算符的优先级(前缀*优先的 是指针,int *fip()中()优先级更高,因此不是指针)
?需要注意的是,以上只是定义指针变量,并不对

应实际的变量,必须对应实际变量后才有意义
自动化系 王雷

8.4 指针变量的引用
? 与地址有关的运算符
?取变量地址运算符 & ?间接访问运算符 *

? 取变量地址运算符&
?其操作对象必须是变量或数组元素(在内存中有

确切的单元地址),而不能是表达式或常量 ?如scanf(“%d”,&a);是将键盘输入的数字串转换 成十进制整数,送入变量a所在的地址单元
自动化系 王雷

? 间接访问运算符*
?操作对象必须是指针变量或指针表达式,即,对

象已指向内存中确切的单元,如 int a,*p; p=&a; //指针p指向变量a 则a=100;与*p=100;作用相同,后者表示取出p的 值,然后把100放入p值所表示的内存单元中 而*p=*p+10也等价于a=a+10 ?p是指针变量,*p则是指针所指向的变量(如a)

自动化系 王雷

8.5 指针变量的运算
指针变量是存放地址量的变量,地址量并不是整数, 地址量的加减并非整数的加减,而是表示内存空间 中按数据类型大小的前后移动 ? 空指针和无效指针
?
? 空指针NULL是C指针类型中的一个特殊值,表示指针变

量的值为空,即不指向任何内存单元,可用于初始化指 针变量 如:int *p=NULL; ? 指针变量不能用其他值初始化 ? 无效指针是一个指针变量无值,如指针变量未赋值或指 针运算超出数组范围
自动化系 王雷

? 关于指针变量的示例程序,见P211例8.1

? 注意与指针相关的运算:&

* = ? P212指针的强制类型转换,可实现不同类型 指针变量间的交叉赋值(应为float *f,x;), 但只在特殊场合使用 ? 对字符的指针变量,可以使用字符串赋值
?如:char *ptr1;

ptr=“how are you!”; //ptr指向该字符串首 个字符的内存地址

自动化系 王雷

两个指针可以相减,或进行关系比较,但必须是相 容指针(见P213和P214说明) ? 两个指针不可以相加(无意义) ? 指针运算例: int *p,*q,a[100]; p=&(a[10]); 则p+3指向的实际地址是&(a[10])+3*sizeof(int), 即a[13]的地址 ? *p++等价于*(p++),表示取出p当前所指单元的内 容,然后p指向后继元素(运算符的优先级) ? *++p等价于*(++p),表示p指向后继元素,再取出p 所指单元的内容
?
自动化系 王雷

?

例8.2 按正向和反向顺序打印一个字符串
#include<stdio.h> main() { char *ptr1,*ptr2; ptr1=“Happy New Year”; ptr2=ptr1; while(*ptr2!=0) putchar(*ptr2++); //正向打印 putchar(?\n?); while(--ptr2>=ptr1) putchar(*ptr2); //反向打印 putchar(?\n?); } //用内存表示解释
自动化系 王雷

?

例8.3 用指针做函数参数实现字符串比较(C8-e3.c)
#include<stdio.h> int udf_strcmp(char *s, char *t); main() { printf(“%d\n”,udf_strcmp(“a string”,”a strange”)); printf(“%d\n”,udf_strcmp(“a strange”,“a string”)); printf(“%d\n”,udf_strcmp(“a string”,“a string”)); } int udf_strcmp(char *s, char *t) { for(;*s==*t;s++,t++) if(*s==?\0?) return(0); return(*s-*t); }

自动化系 王雷

8.6 指向数组元素的指针
地址称为指针的说法有问题 ? 数组名是指针的说法有问题,数组名是一个符号地 址常量,表示数组的首地址,是右值(证明程序 c6-t1.c) ? ANSI C规定,在形参中数组名作为指针使用
?
?

更多参见 http://bbs.chinaunix.net/forum.php?mod=viewthread&t id=2041392

数组的元素视为变量,是左值,可以赋值 ? 指针是个变量,其变量值为某个变量或数组的地址
?

int a[5], *iptr; 则iptr=a;等价于iptr=&a[0];
自动化系 王雷

int a[5]={9,8,7,6,5}; int *iptr; iptr=a;
? 在变量定义时,*用来表示其后所跟的标识符

是一个指针变量名 ? 在表达式中,*是取地址中存放值的操作符, 因此*iptr不能作为左值 ? *(iptr+1)的运算过程
?取出变量iptr的值,即数组a的首地址 ?首地址加上1×sizeof(int),产生新的地址 ?取该新地址中存放的值
自动化系 王雷

?

例8.4 编写字符串复制函数udf_strcpy()
void udf_strcpy1(char s[], char t[]) { //数组方式 int i=0; while ((s[i]=t[i])!=?\0?) i++; }

void udf_strcpy2(char *s, char *t) { //指针方式 while ((*s=*t)!=?\0?) { s++; t++; } }
自动化系 王雷

? ANSI

C工作组规定,不允许把整个数组作为 函数参数,而是传递数组名,并转换为指针 ? 因此,实际使用中,一维数组名可以和指针 变量混用
void udf_strcpy3(char *s, char *t) { //指针方式 while ((*s++=*t++)!=?\0?); } 进一步,由于‘\0?与数值0等同 void udf_strcpy4(char *s, char *t) { //指针方式 while ((*s++=*t++)); }
自动化系 王雷

? 例8.5

将用户输入的数据放入数组中,然后 输出反置后数组的元素(C8-e5.c) ? 要点:采用递归算法,从数组首元素开始, 与尾元素互换,直至到达中间元素

自动化系 王雷

?

例8.6 指针与数组的关系
#include<stdio.h> main() { int a[5]={1,2,3,4,5}; int i,*p; for(i=0;i<5;i++) printf(“%6d”,a[i]); //下标法 printf(“\n”); for(i=0;i<5;i++) printf(“%6d”,*(a+i)); //数组名法 printf(“\n”); for(p=a;p<a+5;p++) printf(“%6d”,*p); //指针变量法 printf(“\n”); }
自动化系 王雷

? 以上访问方式结果相同,但执行效率有差别
?下标法和数组名法执行效果相同,C编译器将a[i]

转换为*(a+i)处理,即先计算元素地址再存取 ?指针变量法最快,指针直接移向元素所在地址 ?下标法较直观,数组名法和指针变量法不直观, 出错检查和处理较复杂
? C程序员的常见做法
?若需要按严格的递增或递减顺序访问数组,用指

针效率高 ?若随机访问数组,用下标简洁明了

自动化系 王雷

? 使用指针表示数组时的注意事项
?数组名不是指针,不能作为左值 ?程序运行过程中指针变量的当前值 #include<stdio.h> main() { int i,a[10],*p; p=a; for(i=0;i<10;i++) scanf(“%d”,p++); for(i=0;i<10;i++) printf(“%6d”,*p++); printf(“\n”); } //找错,指针的访问是动态的

自动化系 王雷

数组越界 ? 深入理解“++”“--”与指针变量的结合使用
?

int a[10],*iptr,*q,u,v=5; iptr=&a[v]; a[4]=40;a[5]=50;a[6]=60; ? q=iptr++; //q指向a[5], iptr指向a[6] ? u=*(iptr++); //u的值为50,iptr指向a[6] ? u=(*iptr)++; //u的值为50,iptr指向a[5],a[5]的值为51 ? u=*iptr++; 同 u=*(iptr++) ? q=++iptr; //q指向a[6],iptr指向a[6] ? u=*(++iptr)或*++iptr; //iptr指向a[6],u的值为60

自动化系 王雷

8.7 指针作为函数参数

自动化系 王雷

8.8 指向字符串的指针变量

自动化系 王雷

8.9 指向多维数组的指针变量

自动化系 王雷

8.10 指针数组

自动化系 王雷

8.11 指向指针的指针

自动化系 王雷

8.12 指针数组作main函数的形参

自动化系 王雷

8.13 指针函数

自动化系 王雷

8.14 指向void量的指针变量

自动化系 王雷

8.15 指向函数的指针

自动化系 王雷

8.16 动态分配内存空间和动态数组

自动化系 王雷

本章重点

自动化系 王雷


相关文章:
C语言复习资料之指针
C语言复习资料之指针_IT认证_资格考试/认证_教育专区。在开始前, 先说说指针。...重点掌握指针变量的定义和引用; 、重点掌握指向数组的指针和通过指向数组的指针...
C语言中指针的运用
C 语言指针的运用 【摘要】C 语言是一种被广泛应用的计算机程序设计语言,“指针”是 C 语言 的精华,是教学的重点和难点,同时又是学好 C 语言的关键。本文...
C语言指针教学中的知识点分析与总结
C 语言指针教学中的知识点分析与总结 摘要:分析指针的基本概念及指针在数组、函数、字符串、动态存储分配等 方面的应用, 提出指针教学过程中易混淆概念及注意事项,...
C语言—指针习题
C语言—指针习题_工学_高等教育_教育专区。第 8 章 指针 二、习题(一) 、是非题 1.运算符“*”有时是单目运算符,有时又可能是双目运算符。 A.对 B.错...
C语言复习重点
C语言复习重点_IT认证_资格考试/认证_教育专区。开发软件各阶段及其作用。 程序...字符指针做为函数参数、一维数组与指针的使用、二维数组与指针的使用(重点:行...
C语言指针用法详解
C语言指针用法详解_IT/计算机_专业资料。C语言指针用法详解 让你不再害怕指针 ...指针指的类型是什么?该指针指向了哪里?(重点注 意) 1.4 指针本身所占据的内存...
C语言最重要的知识点复习资料(认真整理)
C语言最重要的知识点复习资料(认真整理)_工学_高等教育_教育专区。总体上必须...搭配*p[2] 指针数组使用 还有记住脱衣服法则: a[2] 变成 (a+2)+3) *(...
C语言指针讲义
C语言指针讲义_IT认证_资格考试/认证_教育专区。指针程序设计(一)内容 主要 内容...指针程序设计(一)内容 主要 内容 重点 1.指针指针变量的概念 2.指针变量的...
C语言程序设计(指针)
C语言程序设计实验报告实验名称 学姓院名 指针 材料与冶金学院 侯迪文 徐彬 专业班级 学号 成型1104 20110398 2012-12-19 任课教师 实验时间 1 实验目的) 1) ...
C语言各章的重点与难点
C语言各章的重点与难点_工学_高等教育_教育专区。二级考试 各章的重点与难点 ...2 )对函数指针的概念的理解; 3 )函数指针作函数参数; 1 )对流的概念的理解...
更多相关标签: