存储地址的变量的类型就是指针类型
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义
#define NULL 0 int *p=NULL:
–p=NULL与未对p赋值不同 p=NULL与未对p p=NULL与未对 –用途: 避免指针变量的非法引用 用途: 用途 在程序中常作为状态比较 在程序中常作为状态比较 状态
例
int *p; ...... while(p!=NULL) { ...… }
指针变量必须先赋值,再使用 例 main( ) { int i=10; int *p; *p=i; printf(“%d”,*p); }
危险!
…... 整型变量i
2000 2001 2002 2003 2004 2005 2006 …... 随机
变量赋值: 变量赋值:
将数据按该变量定义的类型存入对应的内存单元中 内存单元的内容就是变量的值。 内存单元的内容就是变量的值。
内存中每个字节有一个编号-----地址 内存 0
程序中: int i; float k;
…...
2000 2001 2002 2003
i k
编译或函数调用时为其分配内存单元
&与*运算符
• 两者关系:互为逆运算 • 理解
…... 整型变量i i_pointer &i_pointer 2000 *i_pointer 10 i
2000 2001 2002 2003 2004 2005 2006 2000
10
i_pointer = &i = &(*i_pointer) i = *i_pointer = *(&i)
2.指针运算 2.指针运算
1、指针变量可以和整数做加减操作 指针变量加减一个整数n, 表示指针前后移动n 2、指针变量加减一个整数n, 表示指针前后移动n个元素 地址值增减量等于所指向变量占的字节数sizeof(type) 3、地址值增减量等于所指向变量占的字节数sizeof(type) int a[10]; int *p1=&a[5]; 定义了p1指向整数类型(d=2),初值为a[5] p1指向整数类型(d=2),初值为a[5]的地址 /* 定义了p1指向整数类型(d=2),初值为a[5]的地址 */ p1- -; p1减 p1指向a[4],地址值减(1× 指向a[4],地址值减(1 /* p1减1, p1指向a[4],地址值减(1×sizeof(int)) */ p1+=3; p1加 p1指向a[7],地址值加(3× 指向a[7],地址值加(3 /* p1加3, p1指向a[7],地址值加(3×sizeof(it)) */
内存分配: 内存分配:
系统根据类型为变量分配内存单元 变量内存单元的起始地址即为变量的地址 编译后, 编译后 每个变量名对应一个地址 对变量的访问就是通过这个地址进行的
变量引用: 变量引用:
从变量名对应的地址开始的若干内存单元(字节数由定义 从变量名对应的地址开始的若干内存单元 字节数由定义 类型确定)中取出数据 中取出数据; 类型确定 中取出数据
直接访问与间接访问
直接访问: 直接访问:按变量名存取变量值 间接访问: 间接访问:通过存放变量地址的变量去访问变量
…... 整型变量i 3 20 10
例
i=3;
-----直接访问
2000 2001 2002 2003 2004 2005 2006 2000
变量i_pointer 指针变量
例
*i_pointer=20; 前提条件
定义格式: 基类型名 *指针变量名 〖=&变量名〗 char *p1; int *p2; float *p3; 指针变量赋值 char a,*pa; pa=&a; *pa=‘a’;
指针变量的引用
两个与指针有关的运算符 &:取地址运算符,取其右边变量的地址。 如: &a 取变量a的地址。 *:指向运算符(“间接访问”运算符) 访问右边指针变量所指向的变量。 如:*p 是指针变量p所指向的变量。
7.2.3 函数中用指针变量作形参实现变量的引用传递 #include<stdio.h> void swap(int *p1,int *p2); ; main() { int x,y; printf("Input x,y: "); scanf("%d %d",&x, &y); if(x>y) swap(&x, &y); printf("Sorted: %d %d \n",x,y); } void swap(int *p1,int *p2) { int p; p=*p1; *p1=*p2; *p2=p; }
指针: 指针:一个变量的地址 指针变量: 指针变量:专门存放变量地址的变量叫指针变量
整型变量 …... 指针 2000 2001 变量a
10
变量的地址
变量的内容
2002 2003 2004 2005 2006 …... 2000 变量p 指针变量
指针变量 变量地址(指针) 指向 变量 变量值
地址存入 指针变量
-----间接访问 i_pointer=&i;
…...
例
int k, i, i_pointer=&i; k=i; --直接访问 k=*i_pointer; --间接访问
…... 整型变量i
2000 2001 2002 2003 2004 2005 2006 …... 2000
10
整型变量k
10
变量i_pointer 指针变量
第7章 指针
存储地址的变量的类型就是指针类型 能直接对内存地址操作, 能直接对内存地址操作 实现动态存储管理 容易产生副作用, 容易产生副作用 初学者常会出错 学习时应特别细心, 多动脑、多对比、 学习时应特别细心 多动脑、多对比、多上机
7.1.1 变量的地址和变量的值
内存wenku.baidu.com址: 内存编址
内存是连续的存储空间。 内存是连续的存储空间。 对内存进行了编址 内存编址是连续的, 内存编址是连续的 它的基本单位为字节
4.地址越界问题 4.地址越界问题
指针变量重新赋值后, 其中的地址值发生了变化, 指针变量重新赋值后, 其中的地址值发生了变化, 新的地址值 是否指向所需要的变量, 新的地址值是否有实际意义, 是否指向所需要的变量, 新的地址值是否有实际意义, 系统对 此都不作检查, 此都不作检查, 需要由程序员自己检查
变量i_pointer 指针变量
i_pointer-----指针变量,它的内容是地址量 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址
…...
注意: 注意 (1) 指针变量定义和引用时“*”含义有差别。 指针变量定义和引用时“ ”含义有差别。 在引用中 “*”是运算符 。 ” 运算符,。 表示指针变量指向的变量。 表示指针变量指向的变量。 在指针变量定义时“ ”理解为指针类型定义符 在指针变量定义时“*”理解为指针类型定义符 表示定义的变量是指针变量。 表示定义的变量是指针变量。 (2) 不能引用没有赋值的指针变量。(盲指针) 不能引用没有赋值的指针变量。(盲指针) 。(盲指针 (3) p=&a;是给指针变量 赋值。 是给指针变量p赋值 是给指针变量 赋值。 *p=3; 是给 指向的变量赋值。 是给p指向的变量赋值 指向的变量赋值。 两者含义完全不同。 两者含义完全不同。 (4)必须用同类型的指针给指针变量赋值。 必须用同类型的指针给指针变量赋值。 必须用同类型的指针给指针变量赋值 指针变量只存放地址。 指针变量只存放地址。 不能直接用整型量(或非地址量 赋值给指针变量。 或非地址量)赋值给指针变量 不能直接用整型量 或非地址量 赋值给指针变量。
两个同类型指针可以相减得到一个整数,等于对应元素下标差, 两个同类型指针可以相减得到一个整数,等于对应元素下标差, 等于地址值的差除以地址步进单位。 等于地址值的差除以地址步进单位。 两个指针之间不能进行加法、乘法、除法等算术运算。 两个指针之间不能进行加法、乘法、除法等算术运算。
空指针
–定义:指针变量值为零 定义: 定义 –表示: int * p=0; 表示: 表示
#include<stdio.h> void main() { int a[10],*p; for(p=a;p<a+10;p++) scanf(“%d”,p); for(p=a;p<a+10;p++) printf(“%d”, *p); } #include<stdio.h> void main() { int a[10],i,*p; for(p=a ,i=0; i<10; i++,p++) scanf(“%d”,p); for(p=a ,i=0; i<10; i++,p++) printf(“%d”, *p); }
10
指针变量p
例 main( ) { int i=10,k; int *p; p=&k; *p=i; printf(“%d”,*p); }
3.通过指针引用数组元素 3.通过指针引用数组元素
#include<stdio.h> void main() { int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); for(i=0;i<10;i++) printf(“%d”,a[i]); } #include<stdio.h> void main() { int a[10],i,*p; p=a; for(i=0;i<10;i++) scanf(“%d”,p+i); for(i=0;i<10;i++) printf(“%d”, *(p+i)); }
7.3 指针与数组
数组名代表该数组下标为 的元素地址(数组首地址) 数组名代表该数组下标为0的元素地址(数组首地址) 下标为 数组名与指针是相同的概念 数组名是指针类型的符号常量 7.3.1 指向一维数组元素的指针 1.定义指向数组元素的指针变量 定义指向数组元素的指针变量 int a[10]; /* 数组元素是整型变量 */ int *p; /* 定义 是指向整型变量的指针变量 */ 定义p是指向整型变量的指针变量 p=&a[0]; /* 赋值后 指向 数组的 号元素 */ 赋值后p指向 数组的0号元素 指向a数组的 p=&a[5]; /* 赋值后 指向 数组的 号元素 */ 赋值后p指向 数组的5号元素 指向a数组的 p=&a[0]; 和 p=a; 两句等价
取地址运算符&和指向运算符 的应用。 和指向运算符*的应用 例 7.1 取地址运算符 和指向运算符 的应用。 main() { int m, n; int *p=&m,*q=&n; printf("Input m,n:"); scanf("%d %d",p,&n); /* 指针变量 之前不加 它与 指针变量p之前不加 它与&m相同 */ 之前不加&,它与 相同 printf("m=%d &m=%X\n",m,&m); printf("*p=%d p=%X\n",*p,p); printf("n=%d &n=%X\n",n,&n); printf("*q=%d q=%X\n",*q,q); }
2005
变量是对程序中数据 存储空间的抽象
…...
7.2 指针变量的定义与引用
#include<stdio.h> void main() { int* p; int a; p=&a; scanf(“%d”,&a); printf(“%d %d”,*p, a); scanf(“%d”, p); printf(“%d %d”,*p, a); *p=*p+2; printf(“%d %d”,*p, a); a=a+2; printf(“%d %d”,*p, a); }
数组名与指向数组元素的指针变量。 例 7.4 数组名与指向数组元素的指针变量。 main() { int a[5]={10,20,30,40,50}, *p=a; printf("p=%x p+1=%x\n",p,p+1); printf("a=%x a+1=%x\n",a,a+1); /* a地址值步进单位是 不是 */ 地址值步进单位是2不是 地址值步进单位是 不是10 printf("&a[0]=%x &a[1]=%x \n",&a[0],&a[1]); printf("*p+2=%d *(p+2)=%d\n",*p+2,*(p+2)); /* 注意 注意*p+2和*(p+2)的区别 */ 和 的区别 printf("*a+2=%d *(a+2)=%d\n",*a+2,*(a+2)); }