码迷,mamicode.com
首页 > 编程语言 > 详细

从数组传参看函数的调用和数组的存储情况

时间:2015-02-07 18:56:32      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

首先我们先上例程:

#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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!