一: 内存地址
1:CPU访问内存,是通过内存地址来读写内存数据的,CPU与内存条硬件之间有个地址总线,读数据的时候,CPU通过地址总线将要访问的内存地址告诉内存条,内存条回数据给CPU,这样CPU就能获得内存里面的数据,当CPU通过地址总线将地址告诉内存条时,并将要写入的数据告诉内存,内存将数据存储进去。
2:对于CPU而言地址是唯一的读写内存的方式。
(意思是要读写内存,都是通过内存地址来找到内存中的数据的,没有其他办法)
3:内存地址是一个整数。
4:我们应用程序使用的地址,其实不是真是的物理地址,而是操作系统映射好的虚拟的内存地址。
(如果我们操作的是真是的物理地址,一旦出错误,那么整个操作系统都会崩溃)
5:32位系统与64位系统的虚拟地址是不一样的,前者的地址是有32位的二进制表示的,后者的地址是由64位的二进制表示的,
64位的计算机,使我们使用的内存空间相对于32位更大。64位兼容32位。
#include<stdio.h>
int main()
{
int a,b;
printf("a的地址:%d\n",&a);
printf("b的地址:%d\n",&b);
}
这样访问的是该数据的地址,通过访问地址来访问内存中的数据。
二:C语言指针
1:CPU都是通过内存地址来找到内存的;
2:内存地址是一个整数;
3:指针是存放我们的地址的变量;
4:指针定义在哪里,那么这个变量的内存就分配到哪里;
5:NULL是我们用一个值(0)来表示一个非法的地址,或者是一个不存在的地址,那么这就叫做空地址,所以NULL也叫空;
6:使用指针变量来访问以指针变量位数值的内存地址,那么你必须要保证这个内存是符合逻辑的,没有越界的
三:指针变量的使用
1:指针变量的初始化:
a:如果指针变量暂时没有存放任何内存的地址的数据,那么一般我们回将它初始化为NULL,例如int*p=NULL;
b:通过地址符号获取i变量的地址,然后赋值给指针变量;例如:int a;int*p=&a;
2:通过指针读数据
1:取得指针变量里面存放的内存地址的数据;
2:CPU使用这个地址去访问内存,然后得到数据;
这两步通过(*指针变量)来操作
3:通过指针来写数据:
1:取得指针变量里面存放的内存地址的数据
2:CPU使用这个地址,将数据写入到内存里面;
4:使用指针的时候,要确保指针变量里面存放的地址是那个内存是使用指针的关键;
5:如果指针变量里面存放的地址是一个不可控的地址数据,那么操作系统会杀掉当前的进程,抛出非法错误,比如使用存放NULL的内存地址数据的指针;
6:使用指针变量存放的地址为基地址,然后外加一个偏移量来访问数据;
四:C语言指针与数据
1:数据是存放用一种类型的元素的数据集和,在C语言里面数据的起始地址为数据的名称,例如 1:C语言里面存放内存地址数据的变量就是指针,对于32位程序,那么指针变量的存储空间是4个字节,对于64位程序,指针变量的存储空间是8个字节;
2:指针的实质,指针存放的是一个地址数据,他也是一个变量。
3:指针的定义:
数据类型*变量名称表示遮盖变量存放刚的是所定义的数据类型的内存地址数据。1:C语言里面存放内存地址数据的变量就是指针,对于32位程序,那么指针变量的存储空间是4个字节,对于64位程序,指针变量的存储空间是8个字节;
2:指针的实质,指针存放的是一个地址数据,他也是一个变量。
3:指针的定义:
数据类型*变量名称表示遮盖变量存放刚的是所定义的数据类型的内存地址数据。
4:指针变量内存分配
指针变量定义在哪里,指针变量的内存就分配在哪里,比如是一个全局的指针变量,那么就将内存分配到我们的数据段,大小位4个字节,如果指针变量定义位一个局部变量,那么指针1:C语言里面存放内存地址数据的变量就是指针,对于32位程序,那么指针变量的存储空间是4个字节,对于64位程序,指针变量的存储空间是8个字节;2:指针的实质,指针存放的是一个地址数据,他也是一个变量。
3:指针的定义:
数据类型*变量名称表示遮盖变量存放刚的是所定义的数据类型的内存地址数据。
五:C语言与数组
1:数据是存放同一种类型的元素的数据集合,在C语言里面数组的其实地址位数组的名称,例如
int a[4]
printf("%d\n",a), 打印出来的就是这个数组开始的内存地址
2:数组名称+偏移常量,计算方式是
数据的基地址+sizeof(类型)*偏移常量