什么是指针
指针就是一个地址,如何获取地址?用的是&:取地址符
- 指针就是一个整数
- 获取指针:&
指针变量
存放地址的,也就是存放一个特定的整数(这个的整数可以表示地址)
- 如何产生一个指针变量
类型* 变量名;
类名 *变量名;
- 指针变量的两个重要概念
。指针的类型: 去掉变量名
。指针所指向的类型:去掉变量名和*号
用指针的时候需要保持上述两个类型的一致
int* p;
//类型: int*
//所指向的类型: int --->本质就是指针所操作数据类型
int(*pp)[3]; //--->指针
//int(*)[3];
//int[3]--->pp操作的就是一个数组
int* pArray[3];//--->数组
#include <stdio.h>
int main()
{
int num = 0; //操作系统对于内存会给予一个编号
//printf("%d\n", &num);
printf("%p\n", &num);
int* p; //指针变量
char* pc;
double* pd;
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(char*));
void* pvoid; //待会讲
pc = NULL;
pd = NULL;
pvoid = NULL;
pc = (void*)0; //强制转换语法
//新手误区
int* pNum = # //在创建指针变量赋值的时候,不能这样理解*pNum=&num
//实质还是:pNum=#
int aa = 1001;
pNum = &aa;
printf("%d\n", *pNum); //得到当前地址中的值
//当指针变量指向了普通变量的时候
//*指针变量等效普通变量
*pNum = 10111101; //aa=10111101
printf("%d\n", aa);
return 0;
}
- 不同类型的指针变量
。所有类型指针占用的字节数都是相同 32位系统下都是4个字节
。特殊的指针类型: void*
。专门用来初始化指针变量的东西:NULL
.防止悬浮指针
.防止野指针
。指针变量,获取当前地址中值: *指针变量
指针的运算
- *指针变量: 指针变量所指向的内存存储的值
- p+n或者p-n操作:实质是内存字节偏移,和指向内存存储的数据类型有关
。p+sizeof(指针所指向的类型)*n
。对于一个指针变量来说,不会单独的去偏移,一般要指向一段内存做偏移(数组)
。对于不同类型的指针之间是没有什么算术运算
。p++ 和p-- 也算p+n
#include <stdio.h>
int main()
{
int* p = NULL; //所指向的数据类型:int 大人一步走4米
char* pc = NULL; //所指向的数据类型:char 小孩子一步走1米
printf("%p\n", NULL); //0000000000000000
p = p + 3; //大人走了3步 总共走了: 12米 0xC
//p+sizeof(int)*3 : 0+12
pc = pc + 3; //小孩子走3步 总共走了: 3
//p + sizeof(char) * 3 : 0 + 3
//int a = 1;
//a=a + 3;
printf("%p\n", p);
printf("%p\n", pc);
//p+sizeof(指针所指向的类型)*n
//没有实际含义
//int a = 0;
//int b = 1;
//int* pa = &a;
//int* pb = &b;
//int* pd= pa + pb;
//1001 1002
//2003
return 0;
}
内存四区
#include <stdio.h>
void print()
{
static int num = 1; //这个代码运行的时候只执行一次
//不做初始化默认为0
num++;
printf("%d\n", num);
}
char* returnPoint()
{
//返回局部变量地址,不允许的
//函数调用完,内存会被系统回收(清除所有数据)
char array[10] = "ILoveyou";
//%s 打印方式,从首地址开始,打印到\0
char* p = &array[0];
//把数据存到堆区,返回堆区这段内存的首地址
return p;
}
int main()
{
print(); //num=2;
print(); //num=3;
//num = 3; //错误静态变量有作用
int* p = NULL; //0存放在常量区
//*p = 1234; //不能修改0所在的内存 写入访问权限冲突
//printf("%d", *p);
//------------------------------------------------------
char* str = "ILoveyou"; //解析: 把这段内存的首地址赋值给指针变量
char* pchar;
puts(str);
pchar = "ILoveyou";
//*pchar = 'M'; //写入访问权限冲突。
puts(pchar);
//-------------------------------------------------------
char array[10] = "ILoveyou";
pchar = &array[0];
*pchar = 'M';
puts(array);
int* result = returnPoint();
puts(result);
puts(result);
puts(result);
puts(result);
return 0;
}
万能指针
- 万能指针就是void* 类型的指针变量
- 万能指针在访问数据的时候必须做强制类型类型
#include <stdio.h>
int main()
{
int num = 10;
void* pVoid = # //解析方式: pVoid=# 不是*pVoid=#
printf("%d\n", *(int*)pVoid);
double dNum = 1.11;
pVoid = &dNum;
printf("%.3lf\n", *(double*)pVoid);
//万能指针使用的时候要强制转换为目标类型(就指向数据类型的指针)
int number = 0x00410042; //高低字节:左边:高 右边:低
printf("%d\n", number);
void* p = &number;
char* pp = (char*)p;
//两位十六进制位是不是一个字节
//一个十六进制位是4个二进制位
//8个二进制位是不是一个字节 8个二进制位是不是2个十进制数
//42 00 41 00
printf("%c\n", *pp); //42 -->B //0000005B9FDBF5E4 低地址
char* pc = (char*)p;
printf("%c\n", *(pc + 2));//41-->A //000005B9FDBF5E6 高地址
// -->小端模式 高字节存放到内存地址高的地址上
// -->大端模式 高字节存放到内存地址低的地址上
//十进制:1235
//1高位 5低位
printf("%p\n", pp); //0000005B9FDBF5E4
printf("%p\n", pc + 2); //0000005B9FDBF5E6
//万能指针应用: 统一接口(统一函数传参)
//malloc(void* p,int arrayNum); 会使用这样的函数即可
return 0;
}