本文主要是介绍从数组传参看函数的调用和数组的存储情况,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
首先我们先上例程:
#include <stdio.h>#define SIZE 10
/* 数组为 int 类型的数组*/
const int date[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};int Sum(unsigned char *ar);void main( void )
{int date_sum = 0;date_sum = Sum(date);printf("将数组的数相加等于:%d\n", date_sum);
}/*形参为 unsigned char 类型
*/
int Sum(unsigned char *ar)
{int i;int total = 0;/* 先打印出 ar 的地址*/printf("ar(a[0])的首地址:%x\n\n", ar);for(i=0; i<SIZE; i++){/* 打印出数组的地址和值*/printf("数组ar[%d]地址:%x 值:%d\n", i, &ar[i], ar[i]);total += ar[i];}return total;
}
运行结果为:
本应输出的结果应为:0+1+···+9 = 45
而实际输出的结果却为3,这是为什么呢,让我们先看看函数调用的过程。
函数调用过程:
调用函数首先把参数放在堆栈的临时存储区域中,然后被调函数从堆栈中读取这些参数。但这两个过程并没有相互协调进行,调用函数传递的是实参的类型,而被调用函数则是按照其形参的类型进行数据读取。
从函数调用的原理我们可以看出:调用函数先将 int 类型的数组data[SIZE] 放入首地址为 0x00422fa8 的内存当中,我们用 memory 窗口可观察 0x00422fa8 ~ 0x00422fcb 这部分内存所存储的值,因为数组类型为 int 类型,所以一个元素占4个字节。
而被调函数则是按形参声明的类型类调用堆栈里的数据的,形参声明的类型是 char 类型,所以形参是 1字节1字节 的调用堆栈里的数据的,所以程序 for 循环中调用了10次数组的值相加也只是将 0X00422FA8 ~ 0X00422FB1 的值相加而已,所以导致程序得出错误的结果。
而我们将例程中的:
int Sum(unsigned char *ar);
改为:
int Sum(int *ar);
运行的结果为:
则它将会每隔4个字节读取堆栈的数据。
从这个易错的例子我们可以很好的理解:函数调用的过程、数组在内存中的存储、数组和指针等问题。
这篇关于从数组传参看函数的调用和数组的存储情况的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!