内存
一个内存单元大小为一个字节
32位-32根地址线-==00000*32==-总共2^32种地址序列
C
int a = b//申请内存空间
printf("%p\n",&a);//打印地址(pointer)sizeof
C
printf("%d",sizeof(int));- 数据类型
C
sizeof(char): 1
sizeof(bool): 1
sizeof(short): 2
sizeof(int): 4
sizeof(long): 4
sizeof(long long): 8
sizeof(float): 4
sizeof(double): 8//单位:byte- 指针(指向存储单元首个地址)
C
sizeof(char*): 4//32位环境,2^32
sizeof(char*): 8//64位环境,2^64,单位:byte指针变量的大小取决于地址存放所需的内存空间
内存表示
指针
- 内存单元编号→地址=指针
C
int* p = &a;//地址存储,int*为指针变量,类型为int*。*表明p为指针,int表明指向对象a为int类型- 内存布局C
a = 10//地址:0x0012ff40 p = 0x0012ff40//地址:另外一个 - 取地址 取地址取得的地址为该对象在内存空间中的第一个地址
- 解引用操作符C
*p//通过p中地址找到指向的对象 *p = 20/*等价于*/a = 20 - 语法
C
int* p1,p2,p3;//只有p1是指针变量
int *p1,*p2,*p3;//均为指针变量- 野指针:
- 指针指向的位置是不可知(随机性,初始化,不正确,没有明确限制),指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
- 指针越界:指针指向的范围超过数组名范围时,那么那个指针就是野指针了。
- 规避
- 初始化指针变量
Cint a = 10; int* pa = &a;//确保初始化指针变量- 避免数组越界
C#include<stdio.h> int main() { int arr[10] = { 0 }; int i = 0; int* p = arr; //接收arr数组首元素的地址 for (i = 0; i <= 12; i++)//当i=10的时候已经是非法访问内存了,因为,我数组名的常量表达式内容只有10个元素。 { *p = i; //i每次循环赋值给指针p p++; //指针自增+1,代指arr元素+1 //*p++ = i 也是可以,这里虽说++优先级更高,但是它是后置运算符 } return 0; }- 闲置指针赋值NULL
- 有效性检查
Cif (pa != NULL){ //进行使用 } if (pa == NULL){ //不进行使用 }
- 规避
- 空指针 定义
#define NULL ((void *)0),NULL即为0
指针变量的自增运算
C
chat str[] = "abc";
str++;这里str++的意思是将指针指向下一项,等价于p=p+sizeof(char),内存操作见图 