sizeof获取数组长度

2024-06-18 14:32
文章标签 数组 获取 sizeof 长度

本文主要是介绍sizeof获取数组长度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

昨天开始看《算法导论》这本书,第一个算法就是(直接)插入排序,根据书里给出的伪代码写出了C语言代码,也根据自己的理解重新写了一个。虽然实现了算法的基本要求,但有些细节没有处理好,今天就来完善一下。

在昨天实现的代码中,用来测试的数组int array[] = {5,2,4,6,1,3};是固定的,如果要更换待排序数组话,原来程序中的相关变量就会因为数组长度的改变要做相应的改变。我想要的就是给定任意的数组,在不修改任意代码的条件下实现插入排序。所以,核心问题就是怎么获取给定数组中的元素个数。

自然而然想到的就是sizeof(C/C++中的一个操作符,其功能是返回一个对象或者类型所占的内存字节数)。

一、首先来看看怎么获取整数数组的长度

sizeof的语法形式如下:

(1)sizeof( object ); // sizeof( 对象 );
(2)sizeof( type_name ); // sizeof( 类型 );
(3)sizeof object; // sizeof 对象;

个人喜欢使用sizeof()的形式,因为形式统一,而且可以避免引起混乱导致出错。

假设有一给定数组 int array[] = {5,2,4,6,1,3};

length为数组array[]中的元素个数,那么

length = sizeof(array)/sizeof(*array);            //表达式1
//length = sizeof(array)/sizeof(array[0]);        //表达式2
//length = sizeof(array)/sizeof(int);             //表达式3

上述三个表达式都能得到正确的结果,虽然表达式略有不同,但原理是相同的,即通过sizeof(array)获取整个数组所占的内存字节数,再通过sizeof(*array)或者sizeof(array[0])或者sizeof(int)来获取每个元素所占的字节数,数组所占的字节数除以每个元素所占的字节数就是该数组的元素个数了。

二、字符串数组长度的获取

char str[] = {"This is a string!"};
length = sizeof(str)-1;//包含空格

之所结果要减1,是因为字符串结束符'\0‘在数组中占用了一个字节。

三、源代码

/**************************************
*获取字符串长度(元素个数)  By 羽墨
*print_length.c
***************************************/
#include <stdio.h>void main()
{int array[] = {5,2,4,6,1,3};char str[] = {"This is a string!"};int length = sizeof(array)/sizeof(*array);printf("The length of string '%s' is %d\n",str,sizeof(str)-1);printf("The length of array is %d\n",length);
}

运行结果

The length of string 'This is a string!' is 17
The length of array is 6

四、注意

1、如果在定义数组时就给定了数组的大小,如int array[len];,则不管数组中初始化了多少个(显然应不大于len)元素,最后的数组中的元素个数都是len。所以要想获得数组中真实元素的个数,在初始化数组时应注意这一点。

2、向子函数传递数组后,然后在子函数内部获取数组长度。先来看一个错误示例程序:

int getLength(int array[])
{int length;length=sizeof(array)/sizeof(array[0]); return length;
}len = getLength(array);
printf("The length of array is %d\n",len);

这样得到的结果始终都是1。因为数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址。在本示例中,函数名array传递到子函数后就完全退化为一个指针,该指针指向的是数组array所在的地址,即数组array第一个元素array[0]所在的地址。也就是说系统只是告诉该函数这个存储空间存有数据,但并没有告诉函数这个数据存储空间有多大。sizeof(array)的结果是指针变量array所占内存的字节数,具体大小与系统有关,一般在32位机器上占4个字节,array[0]是int类型,同样占4个字节,所以结果为1。所以要获得数组的长度最好在数组定义所在的区域内。

对于上述情形,查阅资料后给出两种解决方案:

(1)进入子函数后用函数memcpy将数组拷贝出来,函数memcpy所需要的长度由另一个形参传递进来,像这样:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**************************************
*摘自360百科(稍作修改)  By 羽墨
*将数组内容拷贝到函数内部
***************************************/
void fun(char *p, int len)
{char *pData;pData = (char*) malloc (len+1);      //申请内存空间memcpy(pData, p, len+1);             //拷贝数组printf("%s\n",pData);//计算数组大小(略)free(pData);                          //释放内存pData = NULL;
}
int main(int argc, char *argv[])
{char str[] = {"This is a string!"};//初始化数组fun(str, 17);return 0;
}

个人觉得没有必要怎么做。如果能够所需的长度作为形参传递到子函数中,显然就不需要在子函数当中另行计算,so,请看另一个方案。

(2)在子函数外部计算好元素个数后作为形参传递到子函数中进行其他操作。在这里仅给出(直接)插入排序算法的main函数,insert_sort(array,length)函数只需将子函数中用于记录数组元素个数的临时变量length放进子函数的参数列表即可。

#include <stdio.h>void print_array(int *arr, int len);int main(int argc, char *argv[])
{int array[] = {5,2,4,6,1,3};char str[] = {"This is a string!"};int length = sizeof(array)/sizeof(*array);    //计算数组中的元素个数printf("The original");print_array(array, length);insert_sort(array,length);                     //插入排序printf("The sorted");print_array(array, length);                    //输出排序结果return 0;
}void print_array(int *arr, int len)
{int i = 0;for(i=0;i<len;i++){printf("%d ", arr[i]);}
}

这样一来,对于任意的目标序列都可以直接进行排序而不需要修改任何程序语句。

这篇关于sizeof获取数组长度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

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 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过