指针本质
- 指针在本质上也是一个变量
- 指针需要占用一定的内存空间
- 指针用于保存内存地址中的值
不同类型的指针占用的内存大小相同,都为4个字节
#include<stdio.h>
int main()
{
int i = 5;
int* p = &i;
char* q;
printf("指针p的大小:%d\n",sizeof(p));
printf("指针q的大小:%d\n",sizeof(q));
printf("%d %08x\n",i,p);
*p = 10;
printf("%d %08x\n",i,p);
return 0;
}
样例输出
*号的意义
- 在指针声明时,*表示所声明的变量为指针变量
- 在指针使用时,*表示取指针所指内存空间中的值
通过内存给变量赋值
C语言编译器在发现一个程序反复运行时,会在同一个内存空间运行此程序,所以我们可以通过这个漏洞直接操作内存给变量赋值
先写一个输出变量地址的程序
#include<stdio.h>
int main()
{
int i;
printf("%0x\n",&i);
return 0;
}
程序输出i的地址为: 0x61ff1c (这个内存是在我电脑里分配的)
所以程序再次运行还会分配此内存
#include<stdio.h>
int main()
{
int i = 1;
*((int*)0x61ff1c) = 10; //把这个内存里的指赋值为10,我们看下输出
printf("变量i:%d\n",i);
return 0;
}
程序输出变量i的值果然变成了10
传值调用和传址调用
经典案例:swap函数
传值调用
#include<stdio.h>
void swap(int a,int b)
{
int t;
t = a;
a = b;
b = t;
}
int main()
{
int i,j;
i = 2;
j = 3;
swap(i,j);
printf("%d %d\n",i,j);
return 0;
}
程序仍然按照初始化的i,j输出
传址调用
#include<stdio.h>
void swap(int* a,int* b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
int main()
{
int i,j;
i = 2;
j = 3;
swap(&i,&j);
printf("%d %d\n",i,j);
return 0;
}
这样才交换了i,j的值