✨个人主页: 熬夜学编程的小林
系列专栏: 【C语言详解】 【数据结构详解】
指针
1、内存和地址
1.1、内存
2、指针变量和地址
2.1、取地址操作符(&)
2.2、指针变量和解引用操作符(*)
2.2.1、指针变量
2.2.2、如何拆解指针类型
2.2.3、解引用操作符
2.3、指针变量的大小
3、指针变量类型的意义
3.1、指针的解引用
3.2、指针+-整数
3.3、void* 指针
总结
⼀楼:101,102,103...
⼆楼:201,202,203....
...
bit - ⽐特位
byte - 字节
KB
MB
GB
TB
PB
1byte = 8bit
1KB = 1024byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
首先,必须理解,计算机内是有很多的硬件单元,而硬件单元是要互相协同⼯作的。所谓的协同,至少相互之间要能够进行数据传递。 但是硬件与硬件之间是互相独立的,那么如何通信呢?答案很简单,用"线"连起来。 而CPU和内存之间也是有大量的数据交互的,所以,两者必须也用线连起来。 不过,我们今天关心⼀组线,叫做地址总线。
我们可以简单理解, 32位机器有32根地址总线 ,每根线只有两态,表示0,1【电脉冲有无】,那么⼀根线,就能表示2种含义,2根线就能表示4种含义,依次类推。3 2根地址线,就能表示2^32种含义,每⼀种含义都代表⼀个地址。 地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。
#include
int main()
{
int a = 10;
return 0;
}
0x006FFD70
0x006FFD71
0x006FFD72
0x006FFD73
//此结果并不是固定的,因此不必因为自己代码结果不一样觉得有问题。
#include
int main()
{
int a = 10;
&a;//取出a的地址
printf("%p\n", &a);
return 0;
}
#include
int main()
{
int a = 10;
int* pa = &a;//取出a的地址并存储到指针变量pa中
return 0;
}
int a = 10;
int * pa = &a;
char ch = 'w';
pc = &ch;//pc 的类型怎么写呢?
char* pc=&ch;
C语言中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针) 指向的对象,这⾥必须学习⼀个操作符叫解引用操作符(*)。
#include
int main()
{
int a = 100;
int* pa = &a;
*pa = 0;//第七行
return 0;
}
前面的内容我们了解到, 32位机器 假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。如果指针变量是用来存放地址的,那么指针变量的大小就得是4个字节的空间才可以。
同理 64位机器 ,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间, 指针变量的大小就是8个字节。
#include
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%zd\n", sizeof(char*));
printf("%zd\n", sizeof(short*));
printf("%zd\n", sizeof(int*));
printf("%zd\n", sizeof(double*));
return 0;
}
• 32位平台下地址是32个bit位,指针变量大小是4个字节• 64位平台下地址是64个bit位,指针变量大小是8个字节• 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。
//代码1
#include
int main()
{
int n = 0x11223344;
int *pi = &n;
*pi = 0;
return 0;
}
//代码2
#include
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
*pc = 0;
return 0;
}
#include
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;
}
在指针类型中有⼀种特殊的类型是 void* 类型的,可以理解为无具体类型的指针(或者叫泛型指针),这种类型的指针可以用来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进行指针的+-整数和解引用的运算。
#include
int main()
{
int a = 10;
int* pa = &a;
char* pc = &a;
return 0;
}
#include
int main()
{
int a = 10;
void* pa = &a;
void* pc = &a;
*pa = 10;
*pc = 0;
return 0;
}