C语言

您所在的位置:网站首页 c语言在子函数中输出数据 C语言

C语言

2024-06-24 03:50| 来源: 网络整理| 查看: 265

一、通过指针形参在子函数改变常量

大家都知道,C语言子函数的形参,是可以为普通数据类型,也可以为指针的。最初遇到这问题,是在学习STM32的库函数的使用。当初刚接触库函数,对于函数初始化接口,如:

GPIO_Init(GPIOA, &GPIO_InitStructure);

为什么要取初始化结构体变量的地址传递进库函数(&GPIO_InitStructure),而不是直接将结构体变量本身(GPIO_InitStructure)传递进去,不甚了解。直到后来,程序中指针用得多了才有所理解,在这里做个记录。先上代码:

#include void AddNum1(int data) { data++; } void AddNum2(int *data) { (*data)++; //自增运算符“++”优先级高于取值符“*” printf("AddNum2()运行结果:\r\n\r\n*data = %d\r\n", *data); printf(" data = 0x%08X\r\n", data); printf("&data = 0x%08X\r\n\r\n", &data); } int main(void) { int Num1 = 1; //测试AddNum1 AddNum1(Num1); printf("AddNum1()运行结果:\r\n\r\nNum1 = %d\r\n", Num1); Num1 = 1; printf("\r\n\r\n"); //测试AddNum2 AddNum2(&Num1); printf(" Num1 = %d\r\n", Num1); printf("&Num1 = 0x%08X\r\n", &Num1); getchar(); }

运行结果如图:

编译环境为VS2015。

可知,AddNum1没有改变Num1的值,而AddNum2将Num1的值自增了1。分析:

(1)对于子函数形参的理解:

        主函数中的代码“AddNum1(Num1);”。实质上,它将Num1的值赋值给了子函数的形参“data”。

        可将“AddNum1(Num1);”代码理解为运行了以下代码:

void AddNum1() { int data = Num1; data++; }

        通俗的解释就是,子函数声明了一个整型常量“data”,用“data”缓存“Num1”的值。函数中的其他代码,是针对“data”进行运算的,而“Num1” 除了把它自身的值传递给“data”外没有其他任何操作。所以,“AddNum1();” 这个函数并有没改变“Num1”的值。

(2)指针形参的作用:

        我们在对常量,或者是指针进行操作的时候,实质上是对其对应的内存进行操作。对“AddNum2(&Num1);”运行结果以 内存分布图诠释如下:

        

1、可知,Num1的地址是0x00600FFA0C,”AddNum2(int *data)“;声明了一个指针data,并且将Num1的地址赋值给了指  针 data,相当于执行了”data = 0x00600FFA0C;“,此时”*data“ 等同于”Num1“。

2、接下来的”(*data)++;“,操作的是指针data指向的内存”0x00600FFA0C“,这行代码使这个内存块上存储的常量自    增了1,所以”*data = 2“。由1可知,”*data“ 等同于 ”Num1“,所以“*data = 2 = Num1”。

     总结:通过将变量地址传递进子函数,在子函数内操作该地址的内存上存储的数据可达到改变变量的目的。

二、通过指向指针的指针在子函数改变指针的值

  

这种情况我用得比较少。不过在调用内存管理函数的时候可能会用到。如下代码:

主函数声明了一个指向0x00000001地址的char型指针pMemory,并通过子函数申请内存,将申请得到的地址赋值给pMemory

#include #include void GetMemory1(char *pAddr) { pAddr = (char *)malloc(sizeof(char) * 100); } void GetMemory2(char **pAddr) { *pAddr = (char *)malloc(sizeof(char) * 100); printf(" *pAddr = 0x%08x\r\n", *pAddr); printf(" pAddr = 0x%08x\r\n", pAddr); printf(" &pAddr = 0x%08x\r\n\r\n", &pAddr); } int main(void) { char *pMemory = 0x00000001; printf(" pMemory = 0x%08x\r\n", pMemory); printf("&pMemory = 0x%08x\r\n\r\n", &pMemory); GetMemory1(pMemory); printf("/*******GetMemory1();********/\r\n\r\n"); printf(" pMemory = 0x%08x\r\n", pMemory); printf("&pMemory = 0x%08x\r\n\r\n", &pMemory); printf("/*******GetMemory2();********/\r\n\r\n"); GetMemory2(&pMemory); printf(" pMemory = 0x%08x\r\n", pMemory); printf("&pMemory = 0x%08x\r\n", &pMemory); getchar(); }

运行结果:

如上,GetMemory1();并不能将地址赋值给pMemory,而GetMemory2();成功将申请得到的地址赋值给pMemory。分析:

(1)GetMemory1();

        类似于“AddNum1();”,声明了一个指针pAddr,然后将pMemory的值赋值给pAddr。后续代码改变的是pAddr的数据 而没有改变pMemory。所以没有成功地将申请得到的地址赋值给pMemory。

(2)GetMemory2();

        先上图:

       进入函数后,pMemory的地址0x008FF718赋值给了pAddr。malloc();申请得到的内存空间的地址0x02BB4D80赋值给了pAddr所指向的内存“*pAddr”(0x008FF718)。又因为*pAddr = pMemory; ,所以申请得到的内存地址成功赋值给了pMemory。

       综上所述,当数据被传递进子函数,如需通过子函数改变数据的值,需将它的地址作为形参传递进函数(无论常量亦或是指针)。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3