第四讲存储器与指针
(Memory & Pointer)
凌明
trio@seu.edu www.armfans
Ver2.0 2008.3.31
东南大学国家专用集成电路系统工程技术研究中心
wwwasic
目录
存储器,还是存储器!
内存陷阱!
动态内存分配算法
动态内存分配代码讲解
wwwasic
wwwasic
2.1  指针的基本概念
2.1.1  指针是什么?
指针是一个变量,它的值是另外一个变量的地址。
例12.1.2  指针的类型
指针所存储的那个变量类型,就称为指针的类型。
例2      有三个不同类型的指针:
int I[2],  *pI = &I[0];      右边的三个运算有何不同?pI++;
char  C[2], *pC = &C[0];                                                      pC++;
float  F[2], *pF = &F[0];                                                      pF++;
0x00C7指针变量int *p 0x00C7
变量int a
上面例中的两个0x00C7有什么区别?
wwwasic
2.1.3 指针的三个要素
1.指针指向的地址(指针的内容);
2.指针指向的地址上的内容;
3.指针本身的地址。
例3:int A, *pA, **ppA;
pA = &A;
ppA = &pA;指针函数的作用
在复杂的指针都可以通过下表来分析:
&ppA ppA *ppA **ppA
&pA pA *pA
&A              A
wwwasic
第二章指针
2.1.4 指针的大小(指针变量占用的内存空间)
与所用的CPU 寻址空间大小和类型有关,而与指针类型无关。
8位CPU 的指针长度为1~2个字节(51单片机的情况较为复杂,是1~3个字节);16位CPU 的指针长度为2个字节(如MSP430);
32位CPU 的指针长度为4个字节(如Intel 80386)。
上面所述是通常情况,并不是全部符合。2.1.5 指针的初始化
变量在没有赋值之前,其值不定的。对于指针变量,可以表述为:指向不明。程序访问了一个没有初始化的指针:int* p;p 的内存是随机的一个数,比如:0x3FF0073D 程序随即访问内存地址:
0x3FF0073D
0x3FF0073D 是哪里的内存?说不定正好是
Windows 老大要用的内存,你竟敢访问!
Windows 一生气,蓝屏。
一个指向不明的指
针,是非常危险的!!!因此,指针在使用前一定要初始化;在使用前一定要确定指针是非空的!!!wwwasic
2.2  数组与指针
对于数组的两个概念:
1.  C 语言中只有一维数组,数组的大小必须在编译时作为一个常数确定下来。数组的元素可以是任何类型,甚至是数组,由此可以方便地得到多维数组;
2.  数组的任何操作,即使采用数组下标进行的运算都等于对应的指针运算。可以用指针行为替代数组下标的运算。
例4 :
int a[4], *p;
p = a;                //等价于p =&a[0];
*(a+2) = 0;      //等价于a[2] = 0;
p[2] = 0;          //等价于a[2] = 0;
第二章指针
但数组不同于指针:
数组名a是指向数组起始位置的“常量”。
因此,不能对数组名进行赋值操作。
例5:
int a[4], *p;
p = a;                        //正确
a = p;                        //错误
p++;                          //正确
a++;                          //错误
wwwasic
第二章指针
2.3  空指针与通用指针
(1). 空指针
是个特殊指针值,也是唯一对任何指针类型都合法的指针值。一个指针变量具有空指针值,表示它当时没指向有意义的东西,处于闲置状态。空指针值用0 表示,这个值绝不会是任何程序对象的地址。给一个指针赋值0 就表示要它不指向任何有意义的东西。为了提高程序的可读性,标准库定义了一个与0 等价的符号常量NULL,程序里可以写:
p = NULL;              //注意不要与空字符NUL混淆,NUL等价于‘\0’
或者:
p = 0;
注意:
在编程时,应该将处于闲置的指针赋为空指针;
在调用指针前一定要判断是否为空指针,只有在非空情况下才能调用。
wwwasic
wwwasic
(2).通用指针
通用指针可以指向任何类型的变量。通用指针的类型用(void *)表示,因此也称为void 指针。
下面的第三行定义了两个通用指针:
int n, *p;
double  *q;
void      *gp1, *gp2;
可以直接把任何变量的地址赋给通用指针。
例如,有了上面定义,下面赋值是合法的:
gp1 = (void *) &n;
可以把通用指针的值赋给普通的指针。如果被赋值指针与通用指针所指变量的类型不符,需要写强制转换:
p = (int *)gp1;第二章指针
wwwasic
2.4  函数指针
2.4.1 函数指针的定义
函数指针即指向函数地址的指针。利用该指针可以知道函数在内存中的位置。因此也可以利用函数指针调用函数。
函数指针的定义方法:
<;类型> (* <;函数指针名>)(......)
例如:
int (*func)(void )
这里,func 就是一个函数指针。
注意:int *func(void)和int (*func)(void)的区别
int *func(void);              //这是返回一个整型指针的函数
int (*func)(void);//这是一个函数指针

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。