C++面向对象程序设计 - 数组与sizeof、对象指针使用

        在C++中,sizeof是一个运算符,用于获取特定类型或对象在内存中所占用的字节数。这个运算符在多种场景下都非常有用,包括内存管理、性能优化以及理解数据结构在内存中的布局。数组是一种可以存储多个同类型元素的线性数据结构。每个元素在数组中有一个唯一的索引,通常从0开始。数组提供了一种方便的方式来存储和处理一组相关的数据。

        在C++中,获取数组长度并不像获取其他数据类型的大小那样直接,因为数组本身并不包含其长度的信息。所以这篇讲解的是,如何结合sizeof获取数组的长度。并且通过对象指针,也可以获取数组长度。

一、变量类型

        在讲sizeof获取数组长度之前,我们先来了解下C++中变量所占用字节空间,这对后面了解sizeof获取数组长度很有帮助。

整型类型
关键字数的范围字节数描述
short-32768~327672整型
unsigned short0~655352无符号整型
int-2147483648~21474836474短整型
unsigned int0~42949672954无符号短整型
long int-2147483648~21474836474长整型
unsigned long0~42949672954无符号长整型
实型类型
关键字数的范围字节数描述
float-3.4e38~3.4e384单精度
double-1.7e308~1.7e3088双精度
long double-1.1e4932~1.1e493210长双精度

二、获取数据类型大小

        这里我们通过实例代码来演示一下,是否不同数值或大小不一的数值,其类型字节是一样的,代码如下:

#include <iostream>
using namespace std;

int main(){
	// 短整形
	short gender = 1, gender2 = 2;
	cout <<"short byte: " <<sizeof(gender) <<", " <<sizeof(gender2) <<endl;
	// 整型
	int age = 30, age2 = 50, age3 = 8;
	cout <<"int byte: "  <<sizeof(age)  <<", " <<sizeof(age2) <<", " <<sizeof(age3) <<endl;
	// 单精度
	float num = 3.14f, num2 = 86.23f;
	cout <<"float byte: "  <<sizeof(num) <<", " <<sizeof(num2) <<endl;
	// 长双精度
	long int number = 12341238;
	cout <<"long byte: "  <<sizeof(number) <<endl;
	return 0;
}

        从结果上可以看出,可以通过sizeof运算符可以获取数据类型在内存中大小,并且同数据类型的字节空间大小是一样的。如下图:

三、获取对象在内存大小

        对于数组或对象实例,sizeof可以返回整个数组或对象所占用的内存大小,而不仅仅是数组中一个元素或对象一个成员的大小。代码如下:

#include <iostream>
using namespace std;

int main(){
	int nums[5] = {20, 30, 15, 100, 5000};
	cout <<"nums byte: " <<sizeof(nums) <<endl;
	
	double nums2[5] = {20.5, 30.1, 15.8, 100.53, 5000.05};
	cout <<"nums2 byte: " <<sizeof(nums2) <<endl;
	return 0;
}

        从结果可以看出,sizeof运算符输出数组对象的字节空间分别是20和40,int型字节是4,double型字节是8,所以20/4=5,40/8=5。想必大家已经知道如何通过sizeof运算符来计算出数组的长度了。如下图:

四、自定义排序函数

        现在我们可以结合sizeof运算符和数组的一个元素大小,计算出数组的长度。而这里将通过自定义数组排序sortArray()函数方式,来实现int数组排序功能。代码如下:

#include <iostream>
using namespace std;
// 定义数组排序函数
void sortArray(int arr[], size_t len){
	for(size_t i = 0; i < len - 1; i++){
		for(size_t j = i + 1; j < len; j++){
			if(arr[i] > arr[j]){
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
	}
};

int main(){
	int nums[] = {20, 30, 15, 100, 5000};
	size_t numsLen = sizeof(nums) / sizeof(nums[0]); // 计算数组长度
    // 对数组内元素进行排序
	sortArray(nums, numsLen);
	// 打印排序后的数组  
	for(size_t i = 0; i < numsLen; ++i) {  
		cout << nums[i] << " ";  
	}  
	cout << endl;
	return 0;
}

        运行结果如下:

注意:sizeof运算符返回的类型是size_t,这是一个无符号整数类型,用于表示对象的大小。

五、函数模板

        通过自定义sortArray()函数实现了int类型数组元素从小到大排序,但其他类型(如float、double)也希望通过sortArray()排序,那就需要使用函数重载方法来实现,定义多个sortArray()函数且形参数据类型不同。这样会比较麻烦,可以通过函数模板来解决这问题,简单操作。代码如下:

#include <iostream>
#include <string>
using namespace std;
// 定义数组排序函数模板
template <typename T>
void sortArray(T arr[], size_t len){
	for(size_t i = 0; i < len - 1; i++){
		for(size_t j = i + 1; j < len; j++){
			if(arr[i]>arr[j]){
				T temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
	}
};
// 定义打印数组函数模板
template <typename P>
void printArray(P arr[], size_t len, string title){
	cout <<title <<": ";
	// 打印排序后的数组  
	for(size_t i = 0; i < len; ++i) {  
		cout << arr[i] << " ";  
	}  
	cout << endl;
};

int main(){
	int nums[] = {65, 30, 15, 100, 5000};
	size_t numsLen = sizeof(nums) / sizeof(nums[0]); 	// 计算数组长度
	printArray(nums, numsLen, "print int before");		//打印排序前int数组结果
	sortArray(nums, numsLen);							//排序int数组
	printArray(nums, numsLen, "print int after");		//打印排序后int数组结果
	
	float nums2[] = {3.14f, 8.05f, 1.2f, 0.88f, 9.5f};
	size_t nums2Len = sizeof(nums2) / sizeof(nums2[0]); 	// 计算数组长度
	printArray(nums2, nums2Len, "print float before");		//打印排序前float数组结果
	sortArray(nums2, nums2Len);							//排序float数组
	printArray(nums2, nums2Len, "print float after");		//打印排序后float数组结果
	
	long nums3[] = {531138, 782323, 173884, 8813, 64388, 1953};
	size_t nums3Len = sizeof(nums3) / sizeof(nums3[0]); 	// 计算数组长度
	printArray(nums3, nums3Len, "print long before");		//打印排序前long数组结果
	sortArray(nums3, nums3Len);							//排序long数组
	printArray(nums3, nums3Len, "print long after");		//打印排序后long数组结果
	return 0;
}

        通过函数模板定义,可以传入不同数据类型的数组进行排序处理,传入输出结果如下:

六、对象数组指针

        在C++中,引用通常用来指向一个已存在的对象,并且一旦初始化就不能再指向其他对象。对于数组来说,可以有一个指向数组的指针,或者一个指向数组首元素的引用。代码如下:

int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int (*ref)[10] = &arr;        //正确写法
int (&ref)[10] = arr;         //或者这种也是正确写法

        此时,有些人可能在想是否可以在获取数组长度这里再简化点,在调用sortArray()函数时不用传入数组长度,也不用sizeof来计算数组长度呢?当然是可以的,这里可以用对象指针方式,也获取数组长度。现在将函数模板进行简单修改后,再次运行看看效果。代码如下:

#include <iostream>
#include <string>
using namespace std;
// 定义数组排序函数模板
template <typename T, size_t L>
void sortArray(T (&arr)[L]){
	for(size_t i = 0; i < L - 1; i++){
		for(size_t j = i + 1; j < L; j++){
			if(arr[i]>arr[j]){
				T temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
	}
};
// 定义打印数组函数模板
template <typename P, size_t L>
void printArray(P (&arr)[L], string title){
	cout <<title <<": ";
	// 打印排序后的数组  
	for(size_t i = 0; i < L; ++i) {  
		cout << arr[i] << " ";  
	}  
	cout << endl;
};

int main(){
	int nums[] = {65, 30, 15, 100, 5000};
	printArray(nums, "print int before");		//打印排序前int数组结果
	sortArray(nums);							//排序int数组
	printArray(nums, "print int after");		//打印排序后int数组结果
	
	float nums2[] = {3.14f, 8.05f, 1.2f, 0.88f, 9.5f};
	printArray(nums2, "print float before");		//打印排序前float数组结果
	sortArray(nums2);							//排序float数组
	printArray(nums2, "print float after");		//打印排序后float数组结果
	
	long nums3[] = {531138, 782323, 173884, 8813, 64388, 1953};
	printArray(nums3, "print long before");		//打印排序前long数组结果
	sortArray(nums3);							//排序long数组
	printArray(nums3, "print long after");		//打印排序后long数组结果
	return 0;
}

        运行结果如下:

        此时不但在调用sortArray()函数时不用传入数组长度,在函数模板中也能直接获取到数组长度,方便了程序编写,提高效率。

        不过这里需要注意是template中除了定义"typename T"外,还必须定义"size_t L",否则编译过程中会报错"[Error] 'L' was not declared in this scope"。

        当然,在C++中获取数组长度还有其他方法,这里就先讲这些,希望对大家有帮助。

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值