指针定义
内存地址
c
#include <stdio.h>
int main(void)
{
// 创建一个 16 进制的地址
int a = 0xaabbccdd;
printf("%p", &a);
getchar();
return 0;
}
在getchar()
断点中查看内存地址为:
0x0074
对应dd
0x0075
对应cc
0x0076
对应bb
0x0077
对应aa
↑windows
电脑中存储数据采用小端对齐
指针定义和使用
&a
表示取地址*p
表示取值
c
#include <stdio.h>
int main(void)
{
int a = 10;
// 定义指针变量存储变量地址
// 变量类型* 定义
int* p;
p = &a; // 取出变量的内存地址赋值给 p
// 指向的是同一个内存地址
printf("%p\n", &a);
printf("%p\n", p);
// 通过指针间接改变变量的值 *p 表示取值
*p = 100;
printf("%d\n", a);
printf("%d\n", *p);
return 0;
}
所有的指针类型存储的都是内存地址,内存地址是无符号的十六进制整形数
32 位系统中是 4 个字节大小 64 位系统中是 8 个字节大小
- 不建议这样写
c
#include <stdio.h>
int main(void)
{
int a = 10;
int p = &a;
// *p = 20; // 报错
// int * 转换为指针类型,再 *p 取值
*(int *)p = 20;
return 0;
}
指针类型
c
#include <stdio.h>
int main(void)
{
// char 对应 1 字节
char a = 97;
// int 对应 4 字节,修改的是 char 对应的 4 个字节
int* p = &a;
// 不等于
printf("%d\n", a);
printf("%d\n", *p);
return 0;
}
野指针
c
#include <stdio.h>
int main(void)
{
// 不建议将一个变量的值赋值给指针
// 野指针 指针变量指向一个未知的空间
int * p = 100;
// 操作系统 0-255 作为系统空间不允许访问操作
// 操作野指针的空间可能报错
printf("%d\n", *p);
return 0;
}
空指针
c
#include <stdio.h>
int main(void)
{
// 空指针表示内存地址编号为 0 的空间
int * p = NULL;
// 操作空指针一定会报错
*p = 1;
// 可以用于条件判断
if(p == NULL){
// xxx
}
return 0;
}
万能指针
c
#include <stdio.h>
int main(void)
{
int a = 10;
// 万能指针可以接收任意变量类型的内存地址
void * p = &a;
// 报错
// *p = 10;
printf("万能指针所占字节大小:%d\n",sizeof(void *));
// 通过万能指针修改变量的值时,需要找到变量对应的指针类型
*(int *)p = 100;
printf("%d", *(int *)p);
return 0;
}
指针修改const修饰的值
c
#include <stdio.h>
int main(void)
{
const int a = 100; // 存在栈区
// a = 10; // const 不能修改
// 指针间接修改常量的值
int *p = &a;
*p = 1000;
// a 被修改
printf("%d\n", a);
return 0;
}
const 修饰指针
c
#include <stdio.h>
int main(void)
{
int a = 10;
int b = 20;
// 修饰的时 int* 指针类型
const int * p = &a;
// p = 200; // ok 修改 p 的值
// *p = 300; // err 报错,不能修改 const 左值
printf("%d\n", *p);
// 修饰指针变量
int* const p1 = &b;
// p1 = &a; // err 不能修改指针变量
*p1 = 200; // ok
printf("%d\n", b);
// 都修饰的情况
int c = 1;
int d = 2;
// 只读指针
const int * const p2 = &c;
// 不能修改
// p2 = &d;
// *p2 = 2000;
printf("修改前:%d\n", *p2);
// 在 const a = 1; 时,可以通过 *p 指针变量修改 a 的值
// 所以此处 p2 可以通过二级指针来修改
// 一个*:*p3 指向 p2 存的地址。** p3先指向 p2 的地址,再指向 c 的地址
int** p3 = &p2;
*p3 = &d; // *p3 指向 p2 的内存地址
printf("修改后:%d\n", *p2);
**p3 = 30;
printf("int c 被修改为:%d\n", c);
return 0;
}