C/C++中求数组长度的方法数组作为函数参数时退化为指针

2024-04-18 12:38

本文主要是介绍C/C++中求数组长度的方法数组作为函数参数时退化为指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.c/c++中求数组长度的方法

(1) c语言中一般是用宏定义:

#define ARR_LEN(array, length){ length =  sizeof(array) / sizeof(array[0]); }

使用的时候先声明一个length变量,再带入ARR_LEN(array, length);即可获得

(2) c++中可以用模板函数:

template <typename T>int getArrayLen(T &array){return sizeof(array) / sizeof(array[0]);}

比如:

string arr[]={"yruc", "opb", "dfa", "1234", "wangli"};int len=getArrayLen(arr);  //调用模板函数,获得len的值为5

2.但是有个要注意的重大问题:千万不要把已经退化成了指针的参数传入上诉模板函数中!但可以直接传入!,因为数组作为函数参数传入时退化为指针

比如,下面是一个错误示范:

#include<iostream>
#include<cstdlib>
#include<time.h>
using namespace std;
//求数组长度的模板函数
template<typename T>
int getArryLen(T& arr) {return (sizeof(arr) / sizeof(arr[0]));
}
//打印函数
void display(int arr[]) {int len = getArryLen(arr);//在这儿调用了模板函数,但是arr已经退化成了指针,而不是作为数组对象处理,所以不会得到想要的结果cout << "len=" << len << ",  sizeof(arr)=" << sizeof(arr) << endl;
}
int main() {//创建数组int arrNum[] = { 1,2,3};//这儿只是用int数组举例,任何类型的数组都会出现作为函数参数会退化为指针的问题//调用显示函数display(arrNum);system("pause");return 0;
}
//输出的结果却是:len=1,  sizeof(arr)=4.为什么会是这样的结果呢?

因为:当数组传入函数时,传入的是指针,指针仅指向数组头arr[0],不带有任何长度信息,所以就相当于sizeof(int *)/sizeof(arr[0])当然都是1了,因为两个都等于4,都是指向的arr[0]的指针,不带有任何长度信息,所以在自定义函数中传入数组时,还要把数组长度同时传入函数,这样才方便操作数组:比如数组排序啊,交换啊等等无论什么类型的数组都会出现上面的问题!!

那么这个问题怎么来解决呢,那就是不通过函数传参数!!而是直接调用getArrayLen(arr)模板函数即可!如果怕自己忘记,那么就用宏定义吧!

#include<iostream>
#include<cstdlib>
#include<time.h>
using namespace std;
//求数组长度的模板函数
template<typename T>
int getArryLen(T& arr) {return (sizeof(arr) / sizeof(arr[0]));
}int main() {//创建数组int arr[] = { 1,2,3};//调用模板函数获得数组长度int len=getArryLen(arr);//直接传入数组名,而不是把退化成了指针的数组名传入cout << "len=" << len << ",  sizeof(arr)=" << sizeof(arr) << endl;system("pause");return 0;
}
//输出的结果是:len=3,  sizeof(arr)=12.正常了!

 

这篇关于C/C++中求数组长度的方法数组作为函数参数时退化为指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/914807

相关文章

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告:

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

python 3.8 的anaconda下载方法

《python3.8的anaconda下载方法》本文详细介绍了如何下载和安装带有Python3.8的Anaconda发行版,包括Anaconda简介、下载步骤、安装指南以及验证安装结果,此外,还介... 目录python3.8 版本的 Anaconda 下载与安装指南一、Anaconda 简介二、下载 An

Java中将异步调用转为同步的五种实现方法

《Java中将异步调用转为同步的五种实现方法》本文介绍了将异步调用转为同步阻塞模式的五种方法:wait/notify、ReentrantLock+Condition、Future、CountDownL... 目录异步与同步的核心区别方法一:使用wait/notify + synchronized代码示例关键

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数