C语言变量 (Variables)与变量的地址
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例 int i = 3; int *p1; int **p2; p1 = &i; p2 = &p1; **p = 5;
2000 2020
p1 1080 p2 2000
*p2
例 int i, **p; p = &i; () //p是二级指针,不能用变量地址为其赋值 多级指针 例 三级指针 四级指针 int ***p; char ****p;
pc不能指向非字符型变量
例
赋值语句中,被赋值的指针 变量p的前面不能再加“*” 说明符
例 例
不允许直接把一个数赋值给 指针变量 不能用auto变量的地址去初 始化static型指针
2. 指针运算 *
取其指向的内容 单目运算 右结合 优先级二
掌握
[例] int i , *p=&i ; p 2000 *p = 10 ; * &i = 10 ; i = 10 ;
指针(Pointer)的概念
什么类型的变量可以存放变量的地址? 指针类型——存放地址型数据的特殊数据类型
指针变量——专门用于存放地址型数据的变量
变量的指针←→变量的地址
指针变量
变量的地址(指针) 指向 变量 变量值 变量地址存入 指针变量
int a=10; &a 0x0037b000
指针变量指向的数据类型称为基类型
程序 2
main() 主调函数 { int a, b; a = 5; b = 9; 实参 Swap(a, b); printf("a=%d,b=%d",a,b); }
被调 函数
main() { int a, b; a = 5; b = 9; Swap( &a, &b ); printf("a=%d,b=%d",a,b); }
[例] int a[10], *p1=a, *p2=&a[2]; p1 p1 > p2 p1 < p2
[注意]
0 1 p2
2000 a[0] 2002 a[1] 2004 a[2]
若两指针变量并不指向同一区域, 比较无意义。
2018 a[9]
返回
例:编写函数实现两数的互换
程序 1 Trace the execution
temp
5 a 5 9 *x b 5 9 *y x &a &b
&a
y
&b
a
b
x
y
交换的是x 和 y 指向的单元内容
1、数组的指针 数组的指针其实就是数组在内存中的起始地址。而数组在 内存中的起始地址就是数组变量名,也就是数组第一个元素 在内存中的地址。 例:short int a[10]; int a[10];
…...
a
整型变量
pa
指针变量
int *pa=&a;
0x0037b00B
…...
int *pa; pa = &a; 关键是要具备名字, 类型 和 值
int a=10; &a 0x0037b000
10
0x0037b004 0x0037b008
0x0037b000
…...
a
整型变量
pa
指针变量
int *pa=&a;
&a[k] *(a+k) a[k]
2、指向数组的指针变量 如果将数组的起始地址赋给某个指针变量,那么该指针变 量就是指向数组的指针变量。 例:short int a[10], p = a; 元素 地址
p 2000 2002 2004 …... 2018 2000 a[0] a[1] a[2] …... a[9]
0x0037b00B
…...
int *pa; pa = &a;
只能指向同一基类型的变量,否则将引起warning
float a; int *pa = &a; warning C4133: '=' : incompatible types - from 'float *' to 'int *'
3. 指针变量
main() { int a, b; a = 5; b = 9; Swap(a, b); printf("a=%d,b=%d",a,b); }
被调函数
void Swap(int x, int y) { int temp; temp = x; x = y; y = temp; }
temp
5 实参 a 5 b 9 x 9 5 y 9 5 形参
在“stdio.h”文件中,已将 其定义为一个符号常量: #define NULL 0
并不表示指向“0”地址单元 [说明] 1)表示指针变量p 不指向任何有用的单元;
p
0
2)p 被赋了“空值”,但并不等于p 没有值,其值为0 ; 3)任何指针变量或地址都可以与NULL作相等或不相等的比较。
if ( p== NULL )……
…...
10
0x0037b004 0x0037b008
a
整型变量
0x0037b000
pa
指针变量 int *pa;
0x0037b00B
…...
用指针变量要指向的数据类型 作为指针变量的基类型
int a=10; &a 0x0037b000
10
0x0037b004 0x0037b008
0x0037b000
2000 a[0] 2002 a[1] 2004 a[2]
用同类型的指针变量赋值 int i , *p1, *p2; p1 = &i ; p2 = p1; 二者指向同一个目标变量i
p2 p1 2000 2000来自百度文库
2018 a[9]
2000 i
返回
给指针变量赋空值 int *p ; p = NULL ; p=0;
&i 2000 i
记 *p = *&i = i p = &(*p) = &i
返回
多级指针
定义:指向指针的指针 一级指针:指针变量中存放目标变量的地址
例 int *p; int i = 3; p = &i; *p = 5;
p(指针变量) &i 一级指针 i(整型变量) 3
单级间接寻址
二级指针:指针变量中存放一级指针变量的地址
第五部分
变量 (Variables)与变量的地址
(Address)
直接访问:按变量地址存取变量值
如何读写内存中的数据?
int a=0;
&a 0x0037b000 0x0037b001 0x0037b002 0x0037b003
0
a 0
某存储区域
0 0 Contents Contents Contents Contents Contents Contents Contents
下面是对数组元素赋值的几种方法,它们从功能上是等价的
char str[10]; int k; for (k = 0; k < 10; k++) str[k] = 'A' + k; //也可写成*(str+k) = 'A' + k 执行完后,p仍然指向 char str[10]; 数组str的首地址 int k; char *p; p = str; for (k = 0; k < 10; k++) p[k] = 'A' + k; //也可写成*(p+k) = 'A' + k 执行完后,p指向数组 元素str[9]的下一内存 char str[10]; 注意:数组名是地址常量,切不可对其赋值,也不可 单元 int k; 做++或--运算。例如:int a[10];如果在程序中出现a++或 char *p; a--则是错误的。p = str; for (k = 0; k < 10; k++) *p++ = 'A' + k; //相当于 *p = 'A' + k; p++;
概念
将存放地址的变量称为“指针变量 ” 称为
当指针变量得到一个地址时,称指针变量指向该 地址的存储空间。这样可以通过指针变量对该地址存 储空间的数据进行访问。 [指针变量可以指向]
基本类型 构造类型 指 针 函 数
整、实、字 数组、结构体、联合体
返回
用“*”代表“指向”
例如,P1代表指针变量,* P1则表示P1所指向的变量。指针变 量名前的*,表示该变量是指针型的变量。指针变量名为p1,而 非 *p1。
void Swap(int *x,int *y) void Swap(int { x,int y) int temp; { 形参 temp = *x; int temp; *x = *y; temp = x; *y = temp; x = y; 结果有何不同?} y = temp;
程序 1
主调函数
10 &i 2000 i
间接访问 访问p中地址指向的存储单元 i 通过地址访问存储单元 i 通过变量名访问存储单元 i 直接访问
返回
几个重要的等价关系 p 等价于 &i *p 等价于 i p 等价于 &(*p) *(&i ) 等价于i p 2000 若有:int i, *p; p = &i ;
变量 (Variables)与变量的地址 (Address)
间接访问:通过存放变量地址的变量去访问变量 如何读写内存中的数据?
int a=0;
&a 0x0037b000 0x0037b001 0x0037b002 0x0037b003
0
a 0
某存储区域
0 0 Contents Contents Contents Contents Contents Contents 0x0037b000
p1 p2 p2
2000 a[0] 2002 a[1] 2004 a[2]
2018 a[9]
不允许:p1+p2
(语法错且无意义)
返回
指针运算不能乱算
指针和整数的加减运算
同类型指针之间的减法运算
其它运算,比如乘法、除法、浮点运算、 指针之间的加法等,并无意义,所以也 不支持
4. 关系运算
当两个指针变量指向同一个连续的存储区域(数组)时, 则两指针变量可以进行关系运算( 6 种关系运算符 ) 。
…...
a
整型变量
pa
指针变量
int *pa=&a;
0x0037b00B
…...
int *pa; pa = &a; 仅仅是定义了可以指向int型数据 的指针变量,但并未指向a 使其指向a需对指针变量初始化
int a=10; &a 0x0037b000
10
0x0037b004 0x0037b008
0x0037b000
返回
两指针变量相减( - )
当两个指针变量指向同一个连续的存储区域(数组)时,则 两指针变量相减所得整数,表示地址相差的存储单位个数。
[例] int a[10],*p1=a ,*p2=a; p2=p2+2 ; printf(" %d ", p2-p1 ); 2
表示p1和p2相差 2 个存储单位 [注意]
a
b
x
y x 和 y是内部变量
单向值传递
程序 2
主调函数
实参
形参
被调函数
main() { int a, b; a = 5; b = 9; Swap(&a, &b); printf("a=%d,b=%d",a,b); }
void Swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; }
返回
指针变量赋值的几种错误方法: 例 例 int *p = &a; int a; int a; int *pi = &a; char *pc = &a; int a; int *p; *p = &a; int *p; p = 2000; int a; static int *p = &a;
变量a的定义在后,对a的引 用超出了a的作用域
3. 算术运算
加减整数( +、- 、++、- -) 加减整数 该运算作用是使指针移位 [例] int a[10], *p=a ;
*p
p a[0]
2000 p++ 2002 2000 a[0] 2002 a[1] 2004 a[2]
等价于
p ++
*(p+1)
等价于 a[1]
2018 a[9]
[注意] 只有当指针指向一个连续的存储区域时,该运算有意义
a a+1 a+2 ……
p p+1 p+2 ……
*a *(a+1) *(a+2)
……
p[0] *p *(p+1) p[1] *(p+2) p[2] …… ……
p+9 *(a+9) *(p+9) p[9] a+9 注意:p + 1指向数组的下一个元素,而不是简单地 使指针变量p的值+1。其实际变化为p+1*size(size为一个 元素占用的字节数)。例如,假设指针变量p的当前值为 2000,则p+1为2000+1*2=2002,而不是2001。
例 int **p1; int *p2; int i = 3; p2 = &i; p1 = &p2; **p1 = 5;
p1
&p2
p2(指针变量)
&i
i(整型变量) 3
二级指针
一级指针
目标变量
二级间接寻址
定义形式: [存储类型] 如 char **p;
指针本身的存储类型
基类型 **指针名;
*p是p间接指向对象的地址 最终目标变量的数据类型 **p是p间接指向对象的值 **p2, *p1 5 1080 i 3
指针变量的初始化( P222 )
int i, *p = &i ; int a[10], *q = a ;
[注意]
int *p = 100 ; 错
不能将一个整型常量(以及所有非 地址类数据)赋给一个指针变量。
返回
&
用数组的地址给指针变量赋值 p 2000 int a[10] , *p ; p = a;
a 2000 2002 2004 …... 2018 a[0] a[1] a[2] …... a[9]
a a+1 a+2
…… a+9 注意:a+k
int k; for (k = 0; k < 10; k++) a[k] = k; //利用数组下标
int a[10]; int k; for (k = 0; k < 10; k++) *(a+k) = k; //利用数组的指针