先搞清楚指针是个啥?
1G = 1024MB = 10241024KB = 102410241024B = 1024102410241024byte = 2^30字节
32位系统 1 最大支持4G内存条
64位操作系统最大支持 4*17179869184G(4 *264/230)内存
操作系统 2 的内存空间是以字节为单位的,对于内存空间的访问就依赖于内存地址的编址,32位操作系统需要对 2^32 个字节空间编址,那么就需要32位才能表示 2^32 种状态,用无符号整形就足够表示(这也就是为什么以%d打印地址时候会看到地址的值是一个负数),64位操作系统同理,2^64,64位8个字节,使用无符号长整形就能表示。
指针就是一个地址
指针变量
我们知道32位的程序只需要寻址2^32个地址线,指针变量存储的就是给地址的编址的值,因此我们创建的工程的是32位打印指针变量的字节大小就是4byte,64位打印指针变量的字节大小就是8byt
#include <stdio.h>
int main() {
char* ptr_c;
short* ptr_si;
int* ptr_i;
float* ptr_f;
double* ptr_d;
long long int* ptr_L;
printf("%d\n", sizeof(ptr_c));
printf("%d\n", sizeof(ptr_si));
printf("%d\n", sizeof(ptr_i));
printf("%d\n", sizeof(ptr_f));
printf("%d\n", sizeof(ptr_d));
printf("%d\n", sizeof(ptr_L));
return 0;
}
无论什么类型的指针在32位情况下指针大小都是4byte:
无论什么类型的指针在64位情况下指针大小都是8byte:
指针变量是一个变量,它存储了自己指向的变量的地址,通过指针变量解引用我们可以访问和修改指针变量指向的变量的值 3,我们还可以更指针变量引用的变量 4
指针变量指向变量
char ch = 'c';
char* str = &ch;
使用取地址运算符取到的就是字符变量ch的地址,作为初始值去初始化指针变量str,指针变量str存储的值便是ch变量在内存中的地址
定义一个字符数组
char str[5] = {'1', '2', '3' , '4' , '5' };
for (int i = 0; i < 5; ++i) {
printf("%p\n", str + i);
}
printf("%c\n", str[3]);
printf("%c\n", *(str+3));
str字符数组空间是在栈空间开辟的连续的内存空间,str实际就是一个指针变量,它指向了数组存储空间的首元素,它的指向是不能被改变的,实际上可以理解其是一个*const的指针变量,它的指向不能被改变,指针指向不能被改变的知识可以参考 2.变量的作用域和常量中:const修饰指针常见的三种情况
str[3]和*(str+3)是等价的,再次证明数组的名称就是一个指针变量,它指向了一块连续的空间
指针变量解引用及地址偏移
char str[5] = {'1', '2', '3' , '4' , '5' };
char* str_ptr = str;
printf("指针变量str_ptr的地址%p\n", &str_ptr);
printf("指针变量str_ptr存储的地址%p\n", str_ptr);
printf("指针变量str_ptr存储的地址解引用得:%c\n", *str_ptr);
*str_ptr = 'A';
printf("通过解引用改变值后。指针变量str_ptr存储的地址解引用得:%c\n", *str_ptr);
printf("指针变量str_ptr存储的地址偏移一个单位元素的地址%p\n", str_ptr+1);
printf("指针变量str_ptr存储的地址偏移一个单位元素的地址解引用得:%c\n", *(str_ptr+1));
*(str_ptr + 1) = 'B';
printf("通过解引用改变值后。指针变量str_ptr存储的地址偏移一个单位元素的地址解引用得:%c\n", *(str_ptr+1));