赞
踩
计算机中内存的最小存储单位是一字节
称为内存单元 (8个位 0/1)
例如32位int消耗4个字节 即占据4个连续的内存单元
每一个内存单元都有一个唯一的编号
这个编号也就是地址 由指针变量存储
指针的实质就是一个内存地址
对于程序中定义的变量
在对程序进行编译或运行时
系统就会给这个变量分配一个或者多个内存单元
并确定它的内存地址(编号)
32位环境下 所有指针变量的大小都是4字节
64位环境下 所有指针变量的大小都是8字节
也就是说 32位环境下 int* 与 double* 占据的内存单元数量都是4
但是指针的类型不一样 我们不应该混用 尽管物理空间上可以直接赋值相等
其中int类型占据4个字节 double类型占据8个字节
而两者指针变量大小都是4个字节
说明指针变量的大小与指针类型无关
告诉编译器解读地址对应内存空间的方式
比如从首地址开始往高处读多少字节
对于占据大量连续内存单元的数据
其指针只是指向其中的首地址 存的是0x......的十六进制数
因此 我们有void* 也称为万能指针/泛型指针 可以指向任意的类型
(基于固定环境下固定的地址大小)
- int a=10;
- void* p;
- p=&a;
- //要强制转换为int*
- //实际上时告诉编译器
- //要以整型的方式解读对应内存的数据
- printf("%d",*(int*)p);
要强制转换为 int*
实际上时告诉编译器
要以整型的方式解读对应内存的数据
(要想编译器指明用什么方式解读万能指针对应的内存)
- int a=0x12345678;
- int *pi=&a;
- short *ps=&a;
- char *pc=&a;
*pi=12345678
*ps=5678
*pc=78
野指针:指向不明区域或者无效(非法)区域的指针
- int *p;
- *p=10;
这里的*p获得的值是随机的(无法确定)
对于第二行的*p=10 相当于把p变量中存的值当作地址 往对应的内存空间写入10
- int *p=10;
- *p=20;
请问10是什么地址? 对应十六进制为 0x0000000A 这块地址你管不了
实际上0~255(甚至更大)的所有地址值0x00000000~0x000000FF 是保留给操作系统的
如果对范围中的地址对应的内存修改 系统会kill相关程序
tips:我们发现0x后面有8位 每一位是一个十六进制数
实际上 16^8=UINT_MAX(地址没有负数) 这是32位环境下最大的地址值0xFFFFFFFF
- int *p=NULL;
- *p=10;
NULL 其实是宏定义 ((void*)0)
第二行的赋值时非法的
数组名是一个指针常量 固定地址值
不能作为左值被修改 但是可以赋值给其他指针变量
赋值后 两者共同指向同一块内存区域
另外 a[0]==*(a+0) a[1]==*(a+1) a[n]=*(a+n)
sizeof(数组名)获得的数组所有元素总共占有的内存大小
int num=sizeof(数组名)/sizrof(数组名[0]);
int num=数组尾地址-数组首地址 (理解为地址值自动除以了每个元素的大小)
注意:这里的尾地址指的是最后一个元素的下一个位置的开始
指针变量 +1 或者 ++ 实际上是加 1*对应类型的字节数
-1 或 -- 同上
指针计算不是简单的整数相加
如果是一个int * +1的结果是增加一个int的大小
如果是一个char * +1的结果是增加一个char大小
地址之间可以比较大小 例如数组名的比较
指针+指针 ERROR
指针-指针 在数组中 表示两地址之间元素的个数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。