一级指针(间接修改数据,传递地址)
1、函数改变外部变量,内部变量,如下
void changenum(int num)
{
num = 3;
printf("num=%d\n", num);
}
void changenum2(int *p)
{
*p = 4;
printf("num=%d\n", *p);
}
void main()
{
int a = 10;
changenum(a);//值传递 在函数中无法改变主函数中的值 副本机制
changenum2(&a);//指针传递改变值 直接修改值不是副本
system("pause");
}
2、跨进程改变变量(外挂)。这个不好举例子 ,简单说一下,例如一个游戏你想修改你自己的血,但是你有不知道源代码
就无法修改值,但是你可以采用内存搜索找到,你血的地址,用指针进行修改。
3、数组作为参数,(数组会退化为一个指针),一级指针可以作为函数的形式参数接收数组的首地址。
void changenum6(int *p)
{
*p = 33;
for (int* px = p; px < p + 10; px++)
{
printf("%d ", *px);
}
printf("\n");
}
void main()
{
int str[10] = { 1,2,3,4,5,6,7,8,9,0 };
changenum6(str);//传递str退化为一个指针
for (int* px = str; px < str + 10; px++)
{
printf("%d ", *px);
}
system("pause");
}
4、一级指针可以存储一个数组的首地址,可以用两种方式访问,一个是指针的方式一种是下标的方式,
指针循环需要一个一级指针。
void main()
{
int str[10] = { 1,2,3,4,5,6,7,8,9,0 };
int *ptr = str;
for (int i = 0; i < 10; i++)
{
printf("str[%d]=%d ", i, ptr[i]);
}
system("pause");
}
5、一级指针作为函数的返回值返回地址,一定不能返回指向栈的地址
int *changenum4()
{
int b = 4;//auto自动变量
printf("b=%d,&b=%p\n", b, &b);
printf("\n");
return &b;
}
int changenum5()
{int a = 8;//auto自动变量
printf("&changgea=%p\n", &a);
printf("\n");
return a;
}
void main()
{
int *temp = changenum4();
printf("\n\n\n");//在函数执行完成之后,内存被回收了 在没有使用的时候值还是原来的值 若是使用了 值就会发生变化
printf("b=%d,&b=%p\n",*temp, temp);//这里输出的地址和函数中输出的地址一样 但是值不一样
//这是因为b是一个auto变量在函数执行结束之后就会自动消亡 所以值是不对的
&changenum5()是不可以的 因为return也有副本机制 无法取地址 return的数是存放在寄存器中的
//无法赋值 也无法取地址
/printf("a=%d\n", changenum5());//所以函数的返回值是不可以取地址的
system("pause");
}
6、间接访问结构体,创建一个堆上的变量,存储这个变量的地址
struct Info
{
int a;
float b;
};
void main()
{
struct Info myinfo;
printf("%d , %f\n", myinfo.a = 10, myinfo.b = 7.99);//赋值表达式的值等于被赋值变量
struct Info* p1 = &myinfo;
printf("%d , %f\n", (*p1).a = 10, (*p1).b = 7.99);
printf("%d , %f\n", p1->a = 10, p1->b = 7.99);//指针访问结构体的两种形式
struct Info *p2 = (struct Info*)malloc(sizeof(struct Info));
printf("%d , %f\n", (*p2).a = 10, (*p2).b = 7.99);
printf("%d , %f\n", p2->a = 10, p2->b = 7.99);
system("pause");
}