指针知识

指针*p:假设有语句:int a=1;其中变量a的值0x1234存放在地址0x1000的内存中:

变量内存地址
a0x10001

那么当初始化一个指针int *p的时候,CPU会另开辟一片内存单元给指针变量,例如0x1002则:

变量内存地址
a0x10001
p0x1002随机

当进行赋值操作:p=&a;则p中存放的就是变量a的地址*p就是p中存放地址所存储的值,内存单元变化为:

变量内存地址
a0x10001
p0x10020x1000
*p0x1002*(0x1000)=1

空指针

C语言里面的指针可以指向任何有效的数据,也可以不指向任何东西;这后者即所谓的NULL指针。当指向有效数据的时候,对它使用* 做dereference操作就可以取出数据来了;但是对不指向任何数据的指针来进行*操作肯定就没什么意义了,对吧?所以对不指向任何数据的指针做提领其实是个bug。
在现代的操作系统设计中,为了消除程序里面的这种bug,故意分配一些专门的不能访问的内存页,然后将NULL指针安排在里面。这样当程序员不小心在自己的程序中写下对NULL指针的提领操作后,系统运行时就会报错。在windows和linux中,这些内存页被设计者安排在0地址开始对应的那几个页上。实际上,这些页面里面的任何地址都是不能被提领的。* ((char * )0) 不可以,((char )0x12)之类的地址也不可以。很多人认为NULL指针其实就是指向0地址的指针,实际上这是不准确的。虽然很少见,但也有处理器架构将NULL指针安排在非零地址起始的页面内。所以为了程序的可移植性,在需要使用NULL指针的时候,用NULL
宏而来不用0值来初始化指针变量。


强制类型转换

*(int *)0 = 0

C语言中(int * )表示将操作对象强制类型转换为int * 类,即整形指针,这里是将0转换为int * ,所以返回值还是0,不过类型发生了强制转换,成为int * 型。你可以这样想象,有一个指向NULL的int * 指针,和这个地方的(int * )0是等价的,因为当行ansi/iso-c99标准规定NULL指针为0x00000000,即内存中的“第0号地址”。
然后我们继续看外层的* ,这个* 表示对指针指向的内容写内容,写的是一个0,所以,结果是往0x00000000中写数据0,至于写多少个字节的0,需要根据你的平台的字长,以及操作系统等因素来决定。例如:* (int * )0 = 0则是把从内存中地址值为0的内存空间开始,往下涵盖sizeof(int)内存区域,将这段内存区域写入0,比如32内核 int为四个字节,那么上述语句操作结果是将地址值是0x00000000、0x00000001、0x00000002和0x00000003这个四个字节的内存里数据初始化为0。
另外:
UCOSII中 if(OSTCBPrioTbl[prio]==(OS_TCB * )0)指的是判断OSTCBPrioTbl[prio]是否是空指针(是否没有空的TCB位置了)


函数指针:

顾名思义,函数指针就是指向函数的指针变量。
格式为:返回值类型(*指针变量名)(【形参列表】)
形参可有可无,视情况而定
例如:

#include<stdio.h>
int max(int x,int y){return (x>y? x:y);}
int main()
{
    int (*ptr)(int, int);
    int a, b, c;
    ptr = max;
    scanf("%d%d", &a, &b);
    c = (*ptr)(a,b);
    printf("a=%d, b=%d, max=%d", a, b, c);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值