百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

C|求数据类型长度操作符sizeof与求字符串长度函数strlen

bigegpt 2024-10-13 01:25 5 浏览

一、sizeof

sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。

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

功能:一个对象或者类型所占的内存字节数;

说明:sizeof操作符的结果类型是size_t,typedef unsigned int size_t;

原型:extern unsigned int strlen(char *s);

MSDN上的解释为:

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.

其返回值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,一般定义为

在C99及以上标准中,sizeof(char)、sizeof(int)、sizeof(long)、sizeof(long long)、sizeof(float)、sizeof(double)、sizeof(long double)的值分别是1,4,4,8,4,8,16。

结构体的总大小为结构体最宽基本类型成员大小的整数倍,这就是结构体的字节对齐。结构体每个成员相对于结构体首地址的偏移量(offset)都是最宽成员大小的整数倍。如:

struct S1{char c;int i;};

printf(sizeof(S1));

char占1个字节,int占4个字节,VC6中按默认设置得到的结果为8。

结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,所以整个联合体的sizeof也就是每个成员sizeof的最大值。结构体的成员也可以是复合类型,这里,复合类型成员是被作为整体考虑的。

以下是一个利用sizeof操作符求数据类型长度的小实例:

#include <stdio.h>

void main(void)

{

char x = 'a';

char *p = "abcd";

char y[4] = {'a','b','c','d'};

int a = 10;

int *b = &a;

int c[4] = {1,2,3,4};

printf("%d,%d,%d\n",sizeof(x),sizeof(p),sizeof(y));

printf("%d,%d,%d\n",sizeof(a),sizeof(b),sizeof(c));

system("pause");

}

运行结果(32位机):

1,4,4

4,4,16

字符型数据无论是在16位机上还是32位机上都只占一个字节。而整型却不是这样,在16

位机上整型数据是两个字节,而在32位机上是4个字节。因此要在16位机和32位机上分別求其

结果。

首先要知道指针保存的是一个内存地址,其长度是和整型数据一致的。在上述代码中,x是一个字符型变量,其长度肯定是1,因此sizeof(x)的结果是1。p是一个字符指针,其类型为指针类型,指针类型在16位机上占两个宇节,在32位机上占4个字节。y是一个包含4个字符的数组,每个字符长度是1,因此y的长度是4。a是整型变量,其值和指针一样在16位机上长度是2,在32位机长度是4,b是指针变量,其长度同p。c是包含4个整型变量的数组,在16位机上,其长度是8,在32位机上,其长度是16。

以上变量在内存中的存储结构如下图所示:

二、strlen()

strlen(char*)函数求的是字符串的实际长度(字符个数),直到遇到第一个'\0',然后就返回计数值,且不包括'\0'。

格式:strlen (字符数组名)

功能:计算字符串s的(unsigned int型)长度,不包括'\0'在内

说明:返回s的长度,不包括结束符NULL。

char arr[10];
cout<<strlen(arr)<<endl; 
//结果是不定的,因为未初始化,'\0'在内存中的位置不确定
char arr[10]={'\0'}; cout<<strlen(arr)<<endl; //结果为0
char arr[10]="jun"; cout<<strlen(arr)<<endl; //结果为3

三、sizeof和strlen()的区别

sizeof用来返回一个数据类型的长度,而strlen用来返回一个字符串的长度。不过除此之外两者还有本质的区别。

(两者的结果类型是size_t,它在头文件中typedef为unsigned int类型。)

1 sizeof是运算符,strlen是函数。

2 sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。

3 sizeof的参数可以是数据的类型,也可以是变量(此时sizeof后面的括号可以不加),而

strlen只能以char*并且结尾为‘\0‘的字符串作参数。

如下所示:

#include<stdio.h>

#include<string.h>

void main()

{

int a = 3;

printf("%d,%d\n",sizeof(int),sizeof(a));

char *p = "hello123";

printf("%d",strlen(p));

system("pause");

}

执行结果:

4,4

8

sizeof还可以用函数做参数,比如:

short f();
printf("%d\n",sizeof(f()));
输出的结果是sizeof(short),即2。

4 数组做sizeof的参数不退化,传递给strlen就退化为指针了。

5 大部分编译程序在编译时确定sizeof,因此sizeof(x)可以用来定义数组维数;而strlen要在运行时才能计算出来,用来计算字符串的长度,而不是类型占内存的大小;


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 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,

char Arr[3]={'0'};
sizeof(Arr)结果为3;
char *p=Arr;
strlen(p)结果为1;//sizeof(p)结果为4

在传递一个数组名到一个函数中时,它会完全退化为一个指针。

如:


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);
}

四、实例说明

常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度,如果是对指针,结果则会不一样的:

char str[20]="0123456789";

int a=strlen(str); //a=10;

// strlen 计算字符串的长度,以结束符 0x00 为字符串结束。

int b=sizeof(str); //b=20;

//sizeof 计算的则是分配的数组str[20] 所占的内存空间的大小,不受里面存储的内容改变。

上面是对静态数组处理的结果,如果是对指针,结果就不一样了

char* ss = "0123456789";

sizeof(ss) 结果 4;

ss是指向字符串常量的字符指针,sizeof 获得的是一个指针所占的空间,应该是长整型的,所以是4;

sizeof(*ss) 结果 1;

*ss是第一个字符其实就是获得了字符串的第一位'0' 所占的内存空间,是char类型的,占了 1 个字节;

strlen(ss)结果10。


-End-

相关推荐

当Frida来“敲”门(frida是什么)

0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...

服务端性能测试实战3-性能测试脚本开发

前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...

Springboot整合Apache Ftpserver拓展功能及业务讲解(三)

今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...

Linux和Windows下:Python Crypto模块安装方式区别

一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...

Python 3 加密简介(python des加密解密)

Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...

怎样从零开始编译一个魔兽世界开源服务端Windows

第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...

附1-Conda部署安装及基本使用(conda安装教程)

Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...

如何配置全世界最小的 MySQL 服务器

配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...

如何使用Github Action来自动化编译PolarDB-PG数据库

随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...

面向NDK开发者的Android 7.0变更(ndk android.mk)

订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...

信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要

问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...

OpenSSH 安全漏洞,修补操作一手掌握

1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...

Linux:lsof命令详解(linux lsof命令详解)

介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...

幻隐说固态第一期:固态硬盘接口类别

前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...

新品轰炸 影驰SSD多款产品登Computex

分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...