地址与指针
大学C++第5章指针的应用

00:22
前一页 休息
int *p, i=0; p=&67; p=&(i+5);
10
③指针变量是有类型的,所以给指针变 量赋的值不但要是一个地址,而且应该是 一个与该指针变量类型相符的变量的地址。 例如:float f=34.5, *fptr=&f;
C
二、指针变量的关系运算
表示所指变量在内存中的位置关系。 例如:两个指针变量p1、p2指向同一数
组中的元素时:
若p1==p2:表示p1和p2指向数组中 的同一个元素;
若p1<p2:表示p1所指的数组元素在p2所 指的数组元素之前; 若p1>p2:表示p1所指的数组元素在p2所 指的数组元素之后。
变量的数据类型。 例如:int *p;
00:22
前一页 休息 7
3. 在指针定义中,一个“*”只能表示 一个指针变量。
例如:int *p1,p2;
4. 允许声明void类型的指针变量,可以 存储任何类型变量的地址。 例如: void *general; int *point, i; general=&i; point=(int *)general;
x<=*(t+p)停止,此时p即为插入点位置。
重复比较是一个循环操作,循环条件为 x>*(t+p),为了保证位置操作只在数组中进 行,增加一个位置限制p<N。
确定插入位置的程序代码为:
p=0;
t=a;
while (x>*(t+p)&&p<N)
p++;
C语言程序设计_谭浩强_第二版_CH10

}
第十章 指针 10.3 数组的指针和指向数组的指针变量 10.3.2 通过指针引用数组元素 例10.5输出数组中的全部元素。 ②通过数组名计算数组中元素的地址,找出元素的值。
main() {
int a[10],i; for(i=0;i<10;i++){scanf(“%d”,&a[i]);} print(“\n”); for(i=0;i<10;i++){printf(“%d”,*(a+i));} print(“\n”);
}
运行结果为: 100,10 100,10
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.1 通过指针变量访问整型变量
pointer_1 &a
a 100 *pointer_1
pointer_2 &b
b 10 *pointer_2
第十章 指针 10.2 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
pointer_1 &a
a 5 *pointer_1
pointer_2 &b
b 9 *pointer_2
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
b 5 *pointer_2
&b
第十章 指针 10.2 变量的指针和指向变量的指针变量
10.2.1指针变量的引用 例10.3 通过指针变量访问整型变量
pointer_1 &a
a 9 *pointer_1
第十章 指针

19
10.4 字符串与指针
字符串的表示形式
1. 可以用字符数组表示字符串
main() { char string[]=”I love China!”; printf(“%s\n”, string); }
2. 可用字符指针变量来表示
main() { char *string=”I love China!”; printf(“%s\n”, string); }
9
10.2.2 指针变量的引用
& :取地址运算符 * :指针运算符
i_pointer-----指针变量,它的内容是地址量 Eg10.1 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址 main() &*i_pointer等价于i_pointer { (&*i_pointer)++与&*i_pointer++的区别 int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1,*pointer_2); }
21
10.5 指向函数的指针
赋值 函数名代表该函数的入口地址。因此,可用 函数名给指向函数的指针变量赋值。 指向函数的指针变量=[&]函数名;
注意:函数名后不能带括号和参数;函数名前的 “&”符号是可选的。
调用格式 (*函数指针变量)([实参表])
22
用指向函数的指针作函数参数
c语言指针与地址的区别

c语⾔指针与地址的区别
指针由两部分组成,指针的类型和指针的值(也就是变量的地址)。
指针和地址的区别:
地址只是⼀堆⼗六进制的字符,对应着内存条的某段内存,⽽指针本⾝有地址,指针的值也是⼀个地址,指针本⾝还有类型,这与单纯的地址是不同的。
指针和地址的联系:
地址可以强转成⼀个指针,例如:
int a = 1;
//假设a的地址是0x7dfe88
int *p = (int *)0x7dfe88;
附:指针类型的作⽤:
指针的值只是存储了某个变量的⾸地址,但是变量是有类型的,⽐如char是1个字节,int是4个字节,单纯的知道某个变量的⾸地址并⽆法完整的获取整个变量的值,必须知道从⾸地址往下读取多少个字节,指针的类型标明了从⾸地址往下读取多少个字节。
c语言 高级 教程 第五章

a:
b: 在swap px: py:
指针和函数的变元(续)
指针变量使函数可以存取和改变调用函数中的数据对象。getint是一个函 数,它把输入中的数字字符串读入并转换为整数,但有时读入的数无法转 换成整数,此时要返回一个信息,报告此事实(避免冲突需两个通道):
#include <ctype.h> int getch(void); void ungetch(int); /*getint: get next interger from input into *pn*/ int getint(int *pn) { int c, sign; while (isspace(c = getch( ))) ; if (!isdigit(c) && c != EOF && c !=„+‟ && c !=„-‟){ ungetch(c); return 0; } sign = (c == „-‟) ? -1 : 1; if (c == „+‟ || c == „-‟) c = getch( ); for ( *pn = 0; isdigit(c); c = getch( ) ) *pn = 10 * *pn + (c - „0‟); *pn *= sign; if (c != EOF) ungetch(c); return c; }
5.1 指针和地址
内存是线性组织的许多单元(一般称字节)组成的,每一个单元 都可以通过其序号(地址)对之存取,更大的数据对象由多个单 元组成,它们也可以通过其第一个单元的地址进行存取:
P:
C:
p = &c;
通过上述操作以后,如下关系成立: p == &c; /* 这里 &: 取出一个对象的地址*/ c == *p; /*这里 *: 取一个指针所指的对象的值(内容)*/
第9章 指针

第九章指针指针是C语言的一个重要概念,也是C的一个重要特色。
正因为有了指针,C语言才可以灵活有效的表示复杂的数据结构,更方便地处理诸如内存、字符串、数组、函数等。
可以说,不掌握指针就不能掌握C的精华。
一、地址和指针的概念地址的概述1、存储器地址计算机所处理的数据,总是要存储在一定的存储介质上,例如内存。
而这些数据的存储,又是有一定先后顺序的。
因此我们通常将这些存储介质上的一个个用于存放数据的基本单元进行线性编址,即按照一定的顺序给每个存储单元(字节)一个编号,这个编号就是该单元的地址。
一般情况下,地址总是从0开始的一系列整数。
某个地址就代表某个存储单元,就如一个房间号Array码对应于一个实际的房间一样。
2、存储单元的内容这是不同于地址的另一概念,它是指某地址单元内具体存放的数据,如一个字符、一个整数、实数或一个字符串。
例:如右图100,101,102,…,205,206等即是地址;160单元的内容就是字符C,161单元的内容就是字符H,…,等。
3、变量的访问一般情况下,程序中的一个变量就对应存储器的若干个单元,对变量的访问可以简单地认为是通过变量名来对内存单元进行存取操作。
实际上,程序在编译之后,变量名已经转化为了与该变量对应的存储单元地址,因而对变量的访问就是通过地址对存储单元的访问。
1)直接访问按照变量地址来对变量进行存取的方式,称为直接访问方式。
例如:右表中对变量a的读取:printf(“%d”,a),其实是先找到a的地址160,然后从160开始读取一个字节的字符‘C’;同理用scanf(“%d”,&b)输入b的值时,在执行时,直接把从键盘输入的数据‘H’送入从地址为161开始的字节单元中。
2)间接访问通过另一变量间接获取某变量的地址,从而间接实现对原变量的访问的方式,称为间接访问方式。
例如:将变量a的地址160存放在另一个变量当中,见上表p=160,那么,对变量a的访问也可以为:先通过变量p的地址205找到该单元的数据160,再将160视为地址,该地址单元内容就是变量a的值(字符‘C’)。
指针

(main)
9 5 5 9 2000 2002
(swap)
2000 2002 5
...
…...
整型变量a 整型变量b 指针pointer_1 指针pointer_2
指针p1 指针p2
整型p
例 将数从大到小输出
swap(int *p1, int *p2) { int p; 2000 p=*p1; 2002 *p1=*p2; 2004 *p2=p; 2006 } 地址传递 2008 main() 200A { int a,b; int *pointer_1,*pointer_2; 200C scanf("%d,%d",&a,&b); 200E pointer_1=&a; pointer_2=&b; 2010 if(a<b)swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); }
#define NULL 0 int *p=NULL:
p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较
例 例 char *p; int *p1; ...... void *p2; while(p!=NULL) p1=(char *)p2; { ...… p2=(void *)p1; } 表示不指定p是指向哪一种 类型数据的指针变量
…...
例
整型变量i
i=3;-----直接访问
2000 2001 2002 2003 2004 3 20 10
变量i_pointer 2000
2005
2006
指针变量
例
*i_pointer=20; -----间接访问
什么是指针

什么是指针
指针就是地址,而地址就是内存单元的编号。
它是一个从零开始的、操作受限的非负整数。
为什么是操作受限的?因为非负整数与非负整数可以加减乘除,但是指针和指针只能进行相减运算,不能进行其他运算,因为没有意义。
而且进行相减运算也是有条件的:只有同一块空间中的地址才能相减。
而且两个指针变量相减之后的结果是一个常量,而不是指针型变量,即相减的结果是这两个地址之间元素的个数,而不是地址的个数。
这个后面还会再讲。
内存中一个单元指的是一字节,一字节有8 位。
每根地址总线都有两种状态:0 和1。
两根地址总线就有4 种组合,能控制4个内存单元;三根地址总线就有8 种组合,能控制8 个内存单元;n 根地址总线就有2n种组合,能控制2n个内存单元。
那么CPU 总共是通过几根地址总线对内存进行处理的?一般的计算机是32 位的,即32 根地址总线,那么就能够控制232个内存单元,即232字节。
232B=4GB,所以32 位系统的计算机只能控制4GB 的内存。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
28
例5 P97 int **p,*s,k=20; s=&k, p=&s;
29
例 8.1 P97
若改为p=s有何不 同?图怎么改?
#include<stdio.h> main() {int a,b,min,*pa,*pb,*pmin; pa=&a, pb=&b, pmin=&min; scanf(“%d%d”,pa,pb); printf(“a=%d b=%d”,a,b); *pmin=*pa; if(*pa>*pb) *pmin=*pb; printf(“min=%d\n”,min); }
变量i_pointer
2000
2005
2006
指针变量
例
*i_pointer=20; 见P8.2图
-----间接访问 *间接访问运算 符
…...
8.2 指针变量的定义与引用
1. 指针变量与其所指向的变量之间的关系
i_pointer 2000 变量i 3 *i_pointer i &i i=3; *i_pointer i_pointer *i_pointer=3
4、 取地址运算符&与指针运算符* (间接访问运算符)
含义: 取变量的地址 单目运算符 优先级: 14(第二高的级别) 结合性:自右向左 含义: 从某个地址中获取数据 单目运算符 优先级: 14 结合性:自右向左
12
两者关系:互为逆运算
§地址运算符& : 1、只能应用于变量和数组,不可以用于常量表达 13 式或者register类的变量P169. 下列合法的求地址运算是: &x &[x] &2 &(x+y) &x+y 2、&必须放在运算对象的左边,而且运算对象的 类型必须与指针变量的基类型相同. 下列哪些赋值是合法的: float a,*p; int b; *p=&b , *p=a, p=&a, p=&b, *p=&a, *p=b
…...
0x12ff78 0x12ff79 0x12ff7a 0x12ff7b 0x12ff7c 0x12ff7f
5
变量px
0x12ff78
…...
指针变量
8.3 对指针变量的赋值(地址值)
(1) 指针变量的定义的同时赋初值
18 将地址值赋给指针变量 一般形式:数据类型 *指针名=初始地址值; 例 int i; int *p=&i;
当p=&i时, scanf(“%d”,&i)等效于 scanf(“%d”,p)
19
*p=&i;
*只能用于指针变量 另外: p=1000 不合法 (不要将任何其它非地址类型的 数据赋给一个 指针变量)
20
(3) 通过指针变量获取地址值 int i; int *p, *q; p=&i; q=p; 通过指针变量p获取了地址.结果见P95图8.4 (4)通过标准函数获得地址值 P95
直接存取
6
变量实质:代表了:”内存中的某个存储单元” 7 内存的实质:以字节为单位的一片连续的存 储空间.-----每个字节都有一个编号,即” 内存地址” 内存空间是连续的,内存地址也就是连续的, 例P92 图8.1 如:short int a ,b ; float x;
1012 1013 1014
2005 2006
…...
1、int *p=&i; int i; 3、float i; int *p=&i; 5、int i; int *p=&i;
25
下列对哪能些指针变量赋值是正确的? 22
2、int i,*p; p=&i; 4、int i; int *p= i; 6、int i,*p; *p=i;
关于指针使用常见错误
8.4 对指针变量的操作
有三种方式: 1 通过指针来引用一个存储单元; 2 移动指针; 3 指针比较; 8.4.1 通过指针来引用一个存储单元 *p 间接访问指针所指向的存储单元 j=&*i int *p,i=10,j; 例1: p=&i; j=*p; (等效于j=i 或 j=*&i ) j=*p+1; (等效于j=i+1 或 j=*&i+1 )
31
8.4.2对指针变量的操作 移动指针 a,b,c,d,*p,*q; short int
(2) 指针变量 +/- 整数新的地址 p=&b;
q=p+1; 所加的数值:整数*字节数 q=p-1; p++; ++p; 注意:*p++; *++p; 不同于 (*p)++; ++ (*p);
…... 2000 2002 2004 2006 2008 200A 整型变量a 整型变量b 整型变量c 整型变量d 指针变量p 指针变量q
32
(3) 指针变量 - 指针变量 整数(多少个存储单元数)
q-p 1;
9 5 5 9 20 22 2002 2004
...
1的含义 ?P98
200C 200E 2010
1
第八章
地址和指针
本章内容
§变量的地址和指针 §指针变量的定义和基类型 §给指针变量赋值 §对指针变量的操作 §函数间的地址使用指针可以:
使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值
8.1 变量地址和指针
1. 变量与地址 变量的实质是?P10地址是怎么编号的?5
23
地址运算符&在scanf函数中的应用: 例:int k,*q; q=&k; scanf(“%d”,&k); 等效 scanf(“%d”,q);
14
指针运算符示例
…... 2000 2001 整型变量i
15
10
2002
2003 2004 2005 2006 2000
i_pointer = &i = &(*i_pointer) i = *i_pointer = *(&i)
变量必须已说明过; 并要求两者类型一致。 例 float i; 例 int *p=&i; int *p=&i; int i;
例 int i; int *p=i;
例 int i; int *p=&i; int *q=p;
用已初始化指针变量作初值
(2) 指针变量的定义\赋初值分别进行
例 int i; int *p; p=&i;
23
零指针:(空指针)
定义:指针变量值为零 例如: int * p=0;
p不指向任何内存块 24 系统保证该单元不作它用; 表示指针变量的值没有意义。
int *p=NULL;
p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较
例
int *p; ...... while(p!=NULL) { ...… }
25
赋值运算符左边与右边的变量含义不一样 如普通变量: x=x; 26 j=*(p+1) 比较 例2 j=*p+1与 如: int *p ,k=0; p=&k; *p=100; *p=*p+1; (?p和k里的内容是多少?)
*p出现在“=”左面表示指针所指向的存储单元; *p出现在“=”右面表示 指针所指向存储单元的内 容;
指针变量必须先赋值(地址值),再使用!
例 main( ) { int i=10; int *p; *p=i; 危 险! printf(“%d”,*p); } 21
…...
2000 2001 2002 2003 2004 整型变量i
10
指针变量p
随机值
例 main( ) { int i=10,k; int *p; p=&k; *p=i; printf(“%d”,*p); }
变量i_pointer 指针变量
i_pointer-----指针变量,它的内容是地址量2000 *i_pointer----指针的目标变量i,它的内容是数据10 &i_pointer---指针变量占用内存的地址:2004
…...
例8.1 运算符“&”和“*”的使用
#include <stdio.h> void main() {int *px, x=5; px=&x; printf( "&px=0x%x,px=0x%x,*px=%d\n", &px,px,*px); printf( "*&px=0x%x,&*px=0x%x\n",*&px,&*px); printf( "&x=0x%x,x=%d,*&x=%d\n",&x,x,*&x); } 运行结果:
27
如: int *p ,k=0,j,w; p=&k; *p=100; j=*p+1;
关于*与++在指针变量中的运算 两者是同级别的,自右向左运算 例3 判断以下语句哪些与*p=*p+1;等效 *p+=1; ++*p; (*p)++; *p++; *(p+1) *(p++) 比较 *p+1与*(p+1)有何不一样?
30
/*指针在使用前就先赋值*/
8.4.2 移动指针
§什么叫移动指针? 何时有意义? 指针变量+/- 一个整数; 或通过赋值使指针变量指向相邻的存储单元; 指针指向一串连续的存储单元,指针移动才有意 义.