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

2024-08-24 01:32

本文主要是介绍从数组传参看函数的调用和数组的存储情况,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先我们先上例程:

#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://www.chinasem.cn/article/1101062

相关文章

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到