1.指针的含义
指针变量是指存放指针的变量,指针相当于地址,指针变量就是用来存放地址的。
注意:我们日常口头语中说的指针一般都是指指针变量。如定义了int*p,p就是指针变量。
2.*的理解
*在说明p是指针变量,int代表着指针变量p指向的内容是int类型的
3.*的解引用
*p解引用意思是通过p存放的地址找到指针变量指向的对象,*p相当于a,我们可以通过*p的解引用来间接改变a的值,即*p=0这个解引用操作把a的值改成了0。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;
*p = 0;
return 0;
}
4.指针变量的大小
p也是变量,是需要向内存申请一块空间用来存放地址的,由于p是指针变量是用来存放地址的,所以地址的存放需要多大的空间大小,指针变量的大小就是多大。在32位平台下,地址是32个0/1的二进制序列,存储起来需要32个bit位(4个字节),所以在32位平台下指针变量的大小就是4个字节;64位平台下指针变量的大小就是8个字节。
注意:指针变量的大小跟类型无关,只要指针类型的变量在相同大小的平台下大小都是相同的。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//int main()
//{
// int a = 10;
// int* p = &a;
// *p = 0;
//
// return 0;
//}
int main()
{
int a = 0;
int* pa = &a;
char ch = 0;
char* pc = &ch;
short s = 0;
short* ps = &s;
///*printf("%zd\n", sizeof(char*));
//printf("%zd\n", sizeof(short*));
//printf("%zd\n", sizeof(int*));
//printf("%zd\n", sizeof(double*));
//*/
printf("%zd\n", sizeof(pa));
printf("%zd\n", sizeof(pc));
printf("%zd\n", sizeof(ps));
return 0;
}
在64位平台下
在32位平台下
5.地址的打印
用%p来打印地址
6.指针变量类型的意义
a).指针的解引用
指针变量的类型决定了指针进行解引用操作的时候可以访问多大的内存空间大小,int*的指针解引用时可以访问4个字节的大小并且最多只能改变4个字节大小的内容(int类型的大小为4个字节),而char*的指针解引用时可以访问1个字节的大小并且最多只能改变1个字节大小的内容(char类型的大小为1个字节)。
int n = 0x11223344;
int* pi = &n;
*pi = 0;
由上例可以看出,通过int* pi的解引用改变了n的大小
int n = 0x11223344;
char* pc = (char*)&n;
*pc = 0;
由上例子可以看到char*pc的解引用只改变了一个字节的大小
b).指针+-整数
指针类型觉得了指针的步长,指针向前或者向后走一步走多大的距离。
如int*pa,如果pa + 1指针就会向后跳过4个字节的大小(pa为指向int类型的指针),pa + 2指针就会向后跳过(2*4 = 8)个字节的大小;char*pc,如果pc + 1指针就会跳过一个字节的大小(pc为指向char类型的指针变量)
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);
讲解:指针就是地址,由于指针pc和pi都是取n的地址,所以三者地址一样。因为pc为char类型的指针,所以pc + 1就会跳过1个字节的大小,而pi为int类型的指针,所以pi + 1就会跳过4个字节的大小
7.void*指针
void*可以理解为无具体类型的指针(泛型指针),这种类型的指针可以用来接受任意类型的指针,但是void*类型的指针不能直接进行指针的 整数+- 运算和解引用。因为void*类型的指针不明确指向那种类型的指针
8.指针的初始化
创建指针变量的时候如果明确知道指针变量指向的对象应同时赋地址进行指针的初始化,如果不明确知道指针变量指向的对象可以给指针赋值为NULl(0)。如果指针不进行初始化就会产生随机值,那指针就会成为一个野指针,野指针是非常危险的