标签:
首先我们先上例程:
#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个字节读取堆栈的数据。
从这个易错的例子我们可以很好的理解:函数调用的过程、数组在内存中的存储、数组和指针等问题。
标签:
原文地址:http://blog.csdn.net/u012993936/article/details/43604417