Skip to content

内存

一个内存单元大小为一个字节
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;//均为指针变量
  • 野指针:
  1. 指针指向的位置是不可知(随机性,初始化,不正确,没有明确限制),指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
  2. 指针越界:指针指向的范围超过数组名范围时,那么那个指针就是野指针了。
    • 规避
      1. 初始化指针变量
      C
      int a = 10;
      int* pa = &a;//确保初始化指针变量
      1. 避免数组越界
      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;
      }
      1. 闲置指针赋值NULL
      2. 有效性检查
      C
      if (pa != NULL){
      //进行使用
      }
      if (pa == NULL){
      //不进行使用
      }
  • 空指针 定义#define NULL ((void *)0),NULL即为0

指针变量的自增运算

C
chat str[] = "abc";
str++;

这里str++的意思是将指针指向下一项,等价于p=p+sizeof(char),内存操作见图