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

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语言指针总结_学习总结_总结/汇报_实用文档。考研,面试,应聘,笔试 C 语言中的精华是什么,答曰指针,这也是 C 语言中唯一的难点。 C 是对底层操作非常...
C语言指针习题___附答案
C语言指针习题___附答案_IT认证_资格考试/认证_教育专区。一、选择题 1. 变量的指针,其含义是指该变量的___. a)值 c)名 b)地址 d)一个标志 2.若有语...
C语言指针教学中的知识点分析与总结
C 语言指针教学中的知识点分析与总结 摘要:分析指针的基本概念及指针在数组、函数、字符串、动态存储分配等 方面的应用, 提出指针教学过程中易混淆概念及注意事项,...
神一般的C语言指针
今天阅读《C/C++程序员面试指南》中指针一块,以前一知半解的指针问题顷刻间懂了。 下面,可以做个测试,如果下面的指针问题你能够全都解答正确,那么你的 C 语言...
C语言指针练习+答案+讲解
C语言指针练习+答案+讲解_电脑基础知识_IT/计算机_专业资料。第七章 7.1 选择题 指针 1. 若有说明:int a=2, *p=&a, *q=p;,则以下非法的赋值语句是(...
C语言指针,你都了解了吗?
C语言指针,你都了解了吗? - C 语言指针,你都了解了吗? 核心内容: 1、C 语言指针的核心知识点 2、处理指针相关问题的万能措施—-内存分配图 3、C 语言的...
C语言指针选择题
C语言指针选择题_IT认证_资格考试/认证_教育专区 暂无评价|0人阅读|0次下载|举报文档C语言指针选择题_IT认证_资格考试/认证_教育专区。(1) 若有以下定义和语句...
C语言中指针的运用
C 语言指针的运用 【摘要】C 语言是一种被广泛应用的计算机程序设计语言,“指针”是 C 语言 的精华,是教学的重点和难点,同时又是学好 C 语言的关键。本文...
6.C语言指针练习题
6.C语言指针练习题_理学_高等教育_教育专区。一、知识点 1. 2. 掌握指针、地址、指针类型、空指针(NULL)等概念; 掌握指针变量的定义和初始化、指针的间接访问...
C语言指针精选习题和答案
C语言指针精选习题和答案_计算机软件及应用_IT/计算机_专业资料。编者自己选的 一、用指针方法编写一个程序,输入 3 个整数,将它们按由小到大的顺序输出 #include...
更多相关标签: