首页 > 其他分享 >深入理解sizeof

深入理解sizeof

时间:2023-11-09 12:34:22浏览次数:31  
标签:ss char 理解 深入 数组 sizeof strlen size

最近在论坛里总有人问关于sizeof的问题,并且本人对这个问题也一直没有得到很好的解决,索性今天对它来个较为详细的总结,同时结合strlen进行比较,如果能对大家有点点帮助,这是我最大的欣慰了。
一、首先看看sizeof和strlen在MSDN上的定义
首先看一MSDN上如何对sizeof进行定义的:

sizeof Operator

sizeof expression

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type 
(including aggregate types). This keyword returns a value of type size_t.

The expression is either an identifier or a type-cast expression (a type specifier enclosed in 
parentheses).

When applied to a structure type or variable, sizeof returns the actual size, which may include 
padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof 
returns the size of the entire array. The sizeof operator cannot return the size of dynamically 
allocated arrays or external arrays.

然后再看一下对strlen是如何定义的:

strlen

Get the length of a string.

Routine Required Header:
strlen <string.h>

size_t strlen( const char *string );
Parameter
string:Null-terminated string 
Libraries
All versions of the C run-time libraries.

Return Value
Each of these functions returns the number of characters in string, excluding the terminal 
NULL. No return value is reserved to indicate an error.

Remarks
Each of these functions returns the number of characters in string, not including the 
terminating null character. wcslen is a wide-character version of strlen; the argument of 
wcslen is a wide-character string. wcslen and strlen behave identically otherwise.

二、由几个例子说开去

第一个例子:


char* ss = "0123456789";
sizeof(ss) 结果 4 , ss是指向字符串常量的字符指针
sizeof(*ss) 结果 1 , *ss是第一个字符

char ss[] = "0123456789";
sizeof(ss) 结果 11 , ss是数组,计算到\0位置,因此是10+1
sizeof(*ss) 结果 1 , *ss是第一个字符

char ss[100] = "0123456789";
sizeof(ss) 结果是100 , ss表示在内存中的大小 100×1
strlen(ss) 结果是10 , strlen是个函数内部实现是用一个循环计算到\0为止之前

int ss[100] = {0,1,2,3,4,5,6,7,8,9};
sizeof(ss) 结果 400 , ss表示再内存中的大小 100×4
strlen(ss) 错误 , strlen的参数只能是char* 且必须是以''\0''结尾的

char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 4 3 3 2

第二个例子:

class X
{
int i;
int j;
char k;
};
X x;
cout<<sizeof(X)<<endl; 结果 12 ===》内存补齐
cout<<sizeof(x)<<endl; 结果 12 同上

第三个例子:

char szPath[MAX_PATH]

如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小)


三、sizeof深入理解

  • 1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
  • 2.sizeof是算符,strlen是函数。
  • 3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
  • 4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
  • 5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
  • 6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
  • 7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
  • 8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
  • 9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8])
fun(char [])
  • 都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小, 需要这样做:进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
  unsigned char* buf = new unsigned char[len+1]
  memcpy(buf, p1, len);
}
  • 10.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。
  • 11.sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式

四、结束语 sizeof使用场合。


  • 1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:
void *malloc(size_t size), 
  size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
  • 2.用它可以看看一类型的对象在内存中所占的单元字节。
void * memset(void * s,int c,sizeof(s))
  • 3.在动态分配一对象时,可以让系统知道要分配多少内存。
  • 4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
  • 5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
  • 6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

REF: http://www.vckbase.com/document/viewdoc/?id=1054



标签:ss,char,理解,深入,数组,sizeof,strlen,size
From: https://blog.51cto.com/emanlee/8276060

相关文章

  • 【深入理解Java虚拟机】内存分配策略
    本文内容来源于《深入理解Java虚拟机》一书,非常推荐大家去看一下这本书。本系列其他文章:【深入理解Java虚拟机】Java内存区域模型、对象创建过程、常见OOM【深入理解Java虚拟机】垃圾回收机制垃圾收集器与内存分配策略Java技术体系中所提倡的自动内存管理最终可以归结为自动......
  • 有关DFT的条理不清晰理解
    有关DFT的条理不清晰理解本来今年暑假前就写好了,但写的md文件直接上传博客园一直不能正常显示公式,今天刚好解决就上传了一下,解决方法准备附在另外一篇博客寄发现点进随笔还得刷新一下才能正常显示以下内容是在对DFT以及其他变换有基础理解的基础上阐述,因此基本的符号解释和原理......
  • 关于C++链接的一些理解
    无论是.h还是.cpp,都可以写声明或者实体,而且.h和.cpp的前面的名字相同不相同没有任何的影响最终一系列要连接的程序中,必须有且只有一个源文件有main函数,然后从这个main函数开始运行include的作用其实是跟define一样的,是纯文本替换进行替换之后,如果替换的内容是实体,那么就可以直......
  • 软件测试|MySQL LIKE:深入了解模糊查询
    简介在数据库查询中,模糊查询是一种强大的技术,可以用来搜索与指定模式匹配的数据。MySQL数据库提供了一个灵活而强大的LIKE操作符,使得模糊查询变得简单和高效。本文将详细介绍MySQL中的LIKE操作符以及它的用法,并通过示例演示其功能。基本语法MySQL中的LIKE操作符用于模糊匹配数......
  • 正则可视化在线工具-更直观地理解和调试正则表达式的利器
    在工作和学习中,正则表达式是一种强大的工具,用于处理和分析文本数据。它可以帮助我们在海量数据中快速搜索、匹配和提取所需的信息。然而,正则表达式的语法复杂,很多人在编写和调试时可能会遇到困难。为了解决这个问题,我决定自己编写一个正则工具。这个工具旨在提供一个直观且用户友好......
  • 理解GC日志
    输出GC日志通过阅读GC日志,我们可以了解Java虚拟机内存分配与回收策略。先来看一个简单的示例。下面是GC日志:0.115:[GC(System.gc())[PSYoungGen:3020K->600K(38400K)]3020K->608K(125952K),0.0012295secs][Times:user=0.00sys=0.00,real=0.00secs]0.117:[Full......
  • 一文带你零基础深入理解随机变量,概率分布与统计量
    一.随机事件与概率1.1随机现象在自然界和人类活动中,发生的现象多种多样,比如下列这些现象:1.偶数能被2整除2.光的速度是常数 3.一家门店一天之内的订单量4.一个新生儿可能是男生也可能是女生 5.AB实验存在对照组和实验组......
  • BindException、ConstraintViolationException、MethodArgumentNotValidException入参
    Springvalidation验证框架注解Springvalidation验证框架提供了大量接口入参检验注解,注意三个非空注解:@NotNull:验证对象是否不为null,无法查检长度为0的字符串@NotBlank:检查约束(字符串)是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格@NotEmpty:检查(集合)......
  • 理解全序关系
    在数学中,集合 X上的全序、线性序、简单序,或(非严格)排序是在X上的反对称的、传递的和完全的任何二元关系。这意味着如果我们把这种关系指示为≤则下列陈述对于X中的所有a,b和c成立:   如果a≤b且b≤a则a=b(反对称性)   如果a≤b且b≤......
  • 理解偏序关系
    在数学中,特别是序理论中,偏序集合(简写为poset)是配备了偏序关系的集合。这个关系形式化了排序、顺序或排列这个集合的元素的直觉概念。这种排序不必然需要是全部的,就是说不需要但也可以保证在这个集合内的所有对象的相互可比较性。(在数学用法中,全序是一种偏序)。偏序集合定义了偏......