详解C语言中sizeof的使用

Posted TangguTae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解C语言中sizeof的使用相关的知识,希望对你有一定的参考价值。

目录

一、sizeof是什么?

二、sizeof的使用

三、 在字符串数组中sizeof与strlen的区别

四、总结


一、sizeof是什么?

在 C /C++语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符。其作用是取得一个对象(数据类型或者数据对象)的长度(即占用内存的大小,以byte为单位)。其中类型包含基本数据类型(不包括void)、用户自定义类型(结构体、类)、函数类型。数据对象是指用前面提到的类型定义的普通变量和指针变量(包含void指针)。


二、sizeof的使用

在此之前先介绍一下常见的数据类型

常见的基本数据类型char,short int,int,long,long long,float,double

用户自定义数据类型struct(结构体类型),enum(枚举类型),union(联合体类型),arr[](数组类型)

指针类型int*,char*,float*,void*(空指针)

如果初学者不知道各种类型在内存中的大小,可以使用sizeof来计算及验证以上常见的几种数据类型,具体用法如下。

以下代码的运行环境是基于VS2017 ×86环境下得到的结果

基本数据类型的大小可以如下代码段获取

//基本数据类型

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
int main()
{
	printf("%d\\n",sizeof(char));//在内存中占用1个字节
	printf("%d\\n", sizeof(short int));//在内存中占用2个字节
	printf("%d\\n", sizeof(int));//在内存中占用4个字节
	printf("%d\\n", sizeof(long));//在内存中占用4个字节
	printf("%d\\n", sizeof(long long));//在内存中占用8个字节
	printf("%d\\n", sizeof(float));//在内存中占用4个字节
	printf("%d\\n", sizeof(double));//在内存中占用8个字节
	return 0;
}

对于指针类型,无论是char*、int*、void*等都是四个字节(32位编译环境下,每个指针占用4个字节大小的内存,如果是64位编译环境下,每个指针占用8个字节大小)。

//指针类型

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
int main()
{
	char* a;
	int* b;
	void* c;
	float* d;
	printf("%d\\n",sizeof(char*));//在内存中占用4个字节
	printf("%d\\n", sizeof(int*));//在内存中占用4个字节
	printf("%d\\n", sizeof(void*));//在内存中占用4个字节
	printf("%d\\n", sizeof(float*));//在内存中占用4个字节

	printf("%d\\n", sizeof(a));//在内存中占用4个字节
	printf("%d\\n", sizeof(b));//在内存中占用4个字节
	printf("%d\\n", sizeof(c));//在内存中占用4个字节
	printf("%d\\n", sizeof(d));//在内存中占用4个字节
	return 0;
}

与上面的基本数据类型不同,sizeof可以求void*类型的大小,但是不能对void类型求占用空间大小,编译器会提示不允许使用不完整的类型。


通过使用sizeof计算数组的大小很方便

//计算数组的大小

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5 };
	printf("%d\\n", sizeof(arr)/sizeof(arr[0]));
	return 0;
}

用数组占用总空间除以每个元素所占用的空间得到的就是数组元素的个数。sizeof(arr)   (arr是数组名)计算整个数组所占用的内存空间,上述代码求出来sizeof(arr)的值为20,sizeof(arr[0])求的为第一个整型元素所占内存空间大小,得到的结果为4,所以通过相除得到数组总共只有5个元素。

这个地方需要注意一下,单独的来说,arr是数组名,是首元素的地址,只是说在sizeof()里面认为是整个数组,但是如果写成sizeof(arr+0)或者是int*p=arr;sizeof(p),sizeof就认为里面的元素为首元素地址了,这样计算出来得到的结果为1。

还需要注意的是,如果将数组作为实参传递给函数,此时不能用sizeof计算数组大小,因为传递给函数的其实是数组首元素地址,用sizeof得到的并不是整个数组所占用的空间。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

void PrintArrLen(int arr[])
{
	printf("%d\\n", sizeof(arr) / sizeof(arr[0]));//无法计算数组大小,输出结果为1
}
int main()
{
	int arr[] = { 1,2,3,4,5 };
	PrintArrLen(arr);
	return 0;
}

所以一般来说,需要将数组传递给函数,同时也得传递数组的大小,额外定义一个length。

对于自定义数据类型见看了这篇自定义数据类型讲解还不会,可以放下你手中的键盘了_TangguTae的博客-CSDN博客


三、 在字符串数组中sizeof与strlen的区别

在C语言库函数中strlen是用来求解字符串长度,需要声明头文件string.h。实现方式

int my_strlen_2(const char* arr)
{
	
	assert(arr);
	
	while (*arr != '\\0')
	{
		arr++;
		return (1+my_strlen_2(arr));
	}
	return 0;
}

字符串的结束标志位'\\0',strlen所计算的字符串数组的大小不包括'\\0'

如果一个字符串数组char arr[ ]={'a','b','c','d'};是这种不完整的形式(并没有以'\\0'的形式结束)若采用strlen来计算会出现错误,返回的值将会是一个随机值

sizeof计算来字符串数组的大小包括'\\0',用sizeof计算上述数组不会报错。


四、总结

sizeof的使用会出现在平常写代码很多的地方,其用法也不仅仅限于上述的普通用法,在后续的动态内存分配也会经常用到等等。熟悉这一C语言运算符会让你提前对内存这一概念有所了解,对于后面C语言的难点也是重点——指针的理解有一定的帮助。

以上是关于详解C语言中sizeof的使用的主要内容,如果未能解决你的问题,请参考以下文章

C语言中数组长度的计算详解

c语言结构体字节对齐详解

C语言sizeof与strlen详解(附大量笔试题题解过程)

c语言中使用结构体位段的结构体大小

C语言内存对齐详解

C语言中,sizeof返回值代表啥意思?