前言
在C语言中,指针是一个变量,其值为另一个变量的地址。指针变量可以指向任何数据类型,包括整数、字符、数组、结构体等。指针的初始化是指在声明指针变量时为其赋予初始值,使其指向一个有效的内存地址。
#include <stdio.h>
int main() {
int num=100; // int类型占有4个字节
// 打印num的地址
printf("%p\n",&num);//&num 取变量num的地址
//将地址保存起来,有一种变量专门用来存放地址(指针变量)
int* p = #
printf("%p\n",p);
int num2 =* p;//*就是解引用操作符
printf("num2=%d\n",num2);
return 0;
}
指针变量的大小
#include <stdio.h>
int main() {
printf("%d\n",sizeof(char*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(short*));
return 0;
}
结果均为8;
直接赋值:可以通过将指针变量赋值为某个变量的地址来进行初始化。例如,int *ptr = # 这里ptr是一个指向整数的指针变量,通过&操作符获取了num变量的地址并将其赋值给ptr。
动态分配内存:使用C语言中的内存分配函数(如malloc()函数)可以在运行时动态地为指针变量分配内存空间,并将其初始化为所分配的内存地址。例如,int ptr = (int)malloc(sizeof(int)); 这里ptr是一个指向整数的指针变量,通过malloc()函数分配了一个整数大小的内存空间,并将其地址赋值给ptr。
这里有两个问题:
1.一个存储单元有多大?
2.如何编址?
经过仔细的计算和权衡,发现将一个字节给一个对应的地址是比较合适的.
在计算机中,当处理器需要在内存中存取数据的时候,就必然会面临一个问题就是寻址,寻址的前提就是建
立地址。
在计算机的物理结构中,一根地址线可以有0和1两个信号,那么通过这0和1的两个电信号,32根地址线一共
组合起来就可以形成2^32个电信号的组合,通过它们我们就可以建立起2^32个地址,用于处理器识别和访
问。在这里,特别强调一个东西就是,在内存中,数据存储的最小单位是1个字节。为什么要强调这个,是
因为它决定了我们的总的内存大小。由于在内存中,数据存储的最小单位是1个字节,而我们现在有2^32个
地址,即我们需要2^32个字节大小的存储空间(2^32/1024/1024/1024),即4G大小,这也就是为什么32
位地址线的内存大小为4G的原因了。
(1)指针类型决定了指针在被解引用时访问内存空间几个字节
(2)指针类型决定了指针的步长,+1-1向后向前访问几个字节,即跳过几个字节
int指针解引用时默认所指向的内容为in型,flaot指针解引用时默认所指向的内容为float,*p(int*)=100时,
就会以int的存储方式对100进行存储,而*pf(float*)=100时,会以float的存储方式对100进行在内存单元的存储,而int型和float型数据在内存单元的存储方式是不同的,所以以float型存储方式存储100.0时,a(int)的值就会发生变化不再是100。
3、不要将指针大小和指针访问内存单元空间大小记混,两者完全不同且无任何关系
地址的大小根据环境而定,在32位平台下地址大小为4个字节,在64位平台下地址大小为8个字节,假设是在32位平台下,你想以什么样的方式访问内存空间,就给地址定义相对应类型的指针类型,无论你定义什么类型的指针类型,地址本身的大小是特定的不会变的,指针的大小取决于地址的大小,指针类型(char、int)只是决定它访问内存单元时访问几个字节,char*访问1个字节,int*访问4个字节,short*访问2个字节等
总结
指针的初始化是C语言中非常重要的一步,它决定了指针变量能否正确地访问和操作所指向的内存地址。在进行指针初始化时,需要注意以下几点:
-
确保指针变量的类型与所指向的变量类型相匹配,这样才能正确地访问和操作所指向的内存地址。
-
在使用动态分配内存进行指针初始化时,需要确保内存分配操作成功,即分配的内存空间不为NULL,否则将导致程序运行时出现错误。
-
在指针初始化后,需要及时释放所分配的内存空间,以避免内存泄漏问题。