C语言之sizeof 和 strlen 详细介绍

C语言之sizeof 和 strlen

文章目录

  • C语言之sizeof 和 strlen
    • 1. sizeof 和 strlen 的比较
      • 1.1 sizeof
      • 1.2 strlen
      • 1.3 sizeof 和 strlen 的对比
    • 2. 练习
      • 2.1.1 一维数组
      • 2.1.2 字符数组

1. sizeof 和 strlen 的比较

1.1 sizeof

sizeof是C语言中的一个关键字,计算的是变量所占内存空间的大小,单位是字节,如果操作数是数据类型的话,计算的是使用该类型创建的变量所站内存空间的大小

sizeof只关心所占内存空间的大小,不关心内存中存放的什么数据
例如:

#include <stdio.h>
int main()
{int a = 20;printf("%zd\n", sizeof(a));printf("%zd\n", sizeof a);printf("%zd\n", sizeof (int));//printf("%zd\n", sizeof int);//errreturn 0;
}

代码运行结果如下:
在这里插入图片描述

  1. sizeof计算时可以去点括号,但当sizeof计算数据类型创建的变量需要占多少内存空间的时候,括号不能省略,第四句printf代码是错误的
  2. sizeof是单目操作符,返回一个size_t类型的结果,size_t是不是就是无符号整型,打印size_t的结果最好用%zd,否则会有警告
    在这里插入图片描述

1.2 strlen

strlen是C语言中的一个库函数,只用来求字符串的长度。函数原型如下:

size_t strlen ( const char * str );

strlen计算的是字符串中 ’ \0 '之前的长度,当没有 ’ \0 '的时候,strlen还是会继续往后寻找,直到找到 ’ \0 ’ ,所以使用不恰当就会导致越界查找
例如:

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = { 'a','b','c' };char arr2[] = { "abc" };printf("%zd\n",strlen(arr1));printf("%zd\n", strlen(arr2));return 0;
}

代码运行结果如下:
在这里插入图片描述

  1. arr1数组中是以单个字符的形式来存入数组中的,所以数组中只有三个元素,没有 ’ \0 ',当使用strlen求长度的时候,就会越界查找,导致打印一个随机值
  2. arr2数组中是以字符串形式存入数组中的,字符串是默认以 ’ \0 ’ 结束,所以使用strlen求字符串长度时,计算的是’ \0 ’ 之前的字符数量,也就是’a‘ ‘b’ ‘c’ 3个
  3. strlen的返回值也是size_t,也需要使用%zd来打印

1.3 sizeof 和 strlen 的对比

sizeof

  1. sizeof是一个单目操作符
  2. sizeof计算的是操作数所占内存的大小,单位是字节
  3. sizeof不关心内存中放的是什么类型

strlen

  1. strlen是一个库函数,需要包含头文件<string.h>
  2. strlen只用于求字符串的长度,计算的是 ’ \0 '之前字符的个数
  3. strlen关心内存中是否有 ’ \0 ‘,会一直向后查找直到找到’ \0 ',可能会造成查找越界

2. 练习

2.1.1 一维数组

#include <stdio.h>
//数组名的理解
//数组名一般表示数组首元素的地址
//但是有2个例外:
//1. sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
//2. &数组名,数组名表示整个数组,取出的数组的地址
//除此之外,所有遇到的数组名都是数组首元素的地址
int main()
{int a[] = { 1,2,3,4 };printf("%zd\n", sizeof(a));       //- sizeof(数组名)的情况,计算的是整个数组的大小,单位是字节 - 16printf("%zd\n", sizeof(a + 0));   //a表示首元素的地址,加上0之后,还是首元素地址,32位下为4字节,64位下为8字节 - 4/8printf("%zd\n", sizeof(*a));      //a表示首元素的地址,解引用之后得到第一个元素,所以为4个字节 - 4printf("%zd\n", sizeof(a + 1));   //a表示首元素的地址,首地址加上一,指向第二个元素,但是还是地址,是地址大小就为 - 4/8printf("%zd\n", sizeof(a[1]));    //a[1]表示数组中下标为1的元素,也就第二个,int大小为4个字节 - 4printf("%zd\n", sizeof(&a));      //- &数组名的情况,取出的是整个数组的地址,是地址大小就为 - 4/8printf("%zd\n", sizeof(*&a));     // 1. 取地址操作符和解引用操作符相抵消,得到- sizeof(数组名)的情况,计算的是整个数组的大小,单位是字节 - 16// 2. &a 的类型是数组指针,int(*)[4],*&a就是对数组指针解引用访问一个数组的大小,是16个字节 - 16printf("%zd\n", sizeof(&a + 1));  //- &数组名的情况,取出的是整个数组的地址,加一之后,跳过了整个数组,但是还是地址,是地址大小就是 - 4/8printf("%zd\n", sizeof(&a[0]));   //取出数组中下标为0的元素的地址,是地址大小就是 - 4/8printf("%zd\n", sizeof(&a[0] + 1));//取出数组中下标为0的元素的地址,加一之后得到第二个元素的地址,是地址就是 - 4/8return 0;
}

代码运行结果如下:
环境为VS2022,X64,Debug
在这里插入图片描述

2.1.2 字符数组

sizeof

#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zd\n", sizeof(arr));      //- sizeof(数组名)的情况,计算的是整个数组的大小,单位是字节 -6printf("%zd\n", sizeof(arr + 0));  //arr表示首元素地址,加上0之后,还是首元素地址,32位下为4字节,64位下为8字节 - 4/8printf("%zd\n", sizeof(*arr));     //arr表示首元素地址,解引用之后得到第一个元素,所以为4个字节 - 1printf("%zd\n", sizeof(arr[1]));   //arr[1]表示数组中下标为1的元素,char类型大小为1个字节 -1printf("%zd\n", sizeof(&arr));     //- &数组名的情况,取出的是整个数组的地址,是地址大小就为 - 4/8printf("%zd\n", sizeof(&arr + 1)); //- &数组名的情况,取出的是整个数组的地址,加一之后,跳过了整个数组,但是还是地址,是地址大小就是 -4/8printf("%zd\n", sizeof(&arr[0] + 1));//取出数组中下标为0的元素的地址,加一之后得到第二个元素的地址,是地址就是 - 4/8return 0;
}

在这里插入图片描述
strlen

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };//strlen计算的是字符串的长度printf("%zd\n", strlen(arr));     //以字符形式存入数组,从第一个字符'a'向后数,直到遇到'\0',所以会打印随机值printf("%zd\n", strlen(arr + 0)); //首地址+0还是首地址,还是从第一个'a'向后数,直到遇到'\0',所以会打印随机值//printf("%zd\n", strlen(*arr)); err 错误//printf("%zd\n", strlen(arr[1]));err 错误printf("%zd\n", strlen(&arr));    //还是从第一个数组还是数,打印随机值printf("%zd\n", strlen(&arr + 1));//跳过了整个字符数组,从 ' f '字符之后开始数,直到数到 '\0 '之前,随机值printf("%zd\n", strlen(&arr[0] + 1));//跳过了第一个元素,从第二个元素开始数,直到数到 '\0 '之前,随机值return 0;
}

代码运行结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/154080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式常见面试题

简单梳理下二十三种设计模式&#xff0c;在使用设计模式的时候&#xff0c;不仅要对其分类了然于胸&#xff0c;还要了解每个设计模式的应用场景、设计与实现&#xff0c;以及其优缺点。同时&#xff0c;还要能区分功能相近的设计模式&#xff0c;避免出现误用的情况。 什么是…

python -opencv形态学操作

python -opencv形态学操作 1.服饰和膨胀 1.服饰和膨胀 opencv 腐蚀通过cv2.erode实现&#xff0c;膨胀通过cv2.dilate实现&#xff0c;看一下下面代码&#xff1a; from ctypes.wintypes import SIZE from multiprocessing.pool import IMapUnorderedIterator import cv2 i…

76基于matlab的免疫算法求解配送中心选址问题,根据配送地址确定最佳配送中心地址位置。

基于matlab的免疫算法求解配送中心选址问题&#xff0c;根据配送地址确定最佳配送中心地址位置。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 76matlab免疫算法配送中心选址 (xiaohongshu.com)

泛型进阶:通配符

基本概念 对泛型不了解的可以看这篇博客&#xff1a;数据结构前瞻-CSDN博客 一般来说&#xff0c;&#xff1f;在泛型里的使用就是通配符 看看下面的代码 class Message<T> {private T message ;public T getMessage() {return message;}public void setMessage(T m…

网络协议头分析及抓包三次挥手四次握手

数据的封装与传递过程 思考&#xff1a; 应用层调用send后&#xff0c;是如何把数据发送到另一台机器的某个进程的。接收的设备收到数据包后&#xff0c;如何处理给应用层&#xff1f; MTU &#xff1a; Maximum Transmit Unit 最大传输单元 物理接口&#xff08;数据链路层&am…

Lightsail VPS 实例在哪些方面胜过 EC2 实例?

文章作者&#xff1a;Libai 引言 Lightsail VPS 实例和 EC2 实例是云计算领域中两种受欢迎的技术。虽然两者都提供虚拟服务器解决方案&#xff0c;但了解 Lightsail VPS 实例在哪些方面胜过 EC2 实例非常重要。在本文中&#xff0c;我们将探讨这两种技术之间的关键区别&#x…

CI/CD - jenkins

目录 一、部署 1、简介 2、部署 二、配置 三、实时触发 四、自动化构建docker镜像 五、通过ssh插件交付任务 六、添加jenkins节点 七、RBAC 八、pipeline 九、jenkins结合ansible参数化构建 1、安装ansible 2、新建gitlab项目 3、jenkins新建项目playbook 一、部…

choices参数的使用、MVC和MTV的模式、创建表对表关系的三种创建方式

【1】choices参数的使用 应用场景&#xff1a;针对表中可能列表完全的字段&#xff0c;采用choices参数 例如&#xff1a;性别&#xff0c;代码如下 # 1.创建一张表class gender_info(models.Model):name models.CharField(max_length32)password models.CharField(max_lengt…

大数据题目的解题技巧

目录 大数据题目的技巧总括 实例精析 实例一 实例二 实例三 大数据题目的技巧总括 &#xff08;1&#xff09;哈希函数可以把数据按照种类均匀分流&#xff1b; &#xff08;2&#xff09;布隆过滤器用于集合的建立与查询&#xff0c;并可以节省大量空间&#xff1b; &…

ubuntu 安装 gparted

前提环境&#xff1a; 阿里云的源。 sudo apt update sudo apt upgrade sudo apt install gparted 搜索&#xff1a;

Android AIDL中使用Surface问题

1.构建ITest.aidl文件 package com.xxx.xxxx;import android.view.Surface;interface IMonitorService {boolean addSurface(in Surface surface);boolean removeSurface(in Surface surface); } 2.构建时报错 3.Surface源码分析 android.view.Surface中包含两个Surface类&am…

万字解析设计模式之 装饰者模式

一、装饰者模式 1.1概述 装饰者模式是一种结构型设计模式&#xff0c;它允许在运行时动态地为一个对象添加额外的职责。它以一种透明的方式来扩展对象的功能&#xff0c;而不需要通过子类来实现。在装饰者模式中&#xff0c;有一个基本对象&#xff0c;也称为组件&#xff0c;…

SpringBean的配置详解 --中

目录 Bean的初始化和销毁方法配置 Bean的初始化和销毁方法配置 扩展 Bean的实例化 Bean的初始化和销毁方法配置 当lazy-init设置为true时为延迟加载&#xff0c;也就是当Spring容器加载的时候&#xff0c;不会立即创建Bean实例&#xff0c;等待用到时再创建Bean实例并存储到单…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战一使用鸿蒙登录组件实现客户端登录

目录 概述使用云端一体化开发模板创建项目工程创建登录入口页面集成登录SDK组件依赖登录组件SDK使用登录组件SDK 开启“手机号码”和“邮箱地址”认证方式 概述 通过本次课程&#xff0c;我们将学习怎么使用云端一体化开发模板来创建云开发工程&#xff0c;以及如何使用鸿蒙登…

外卖小程序系统:数字化餐饮的编码之道

在当今数字化时代&#xff0c;外卖小程序系统成为了餐饮业的一项技术巨制。这个系统不仅提供了便捷的点餐体验&#xff0c;更通过先进的技术手段&#xff0c;实现了高效订单处理、实时配送追踪以及个性化推荐。让我们深入了解外卖小程序系统的技术魔法&#xff0c;一起揭秘数字…

SSL加密

小王学习录 今日摘录前言HTTP + SSL = HTTPSSSL加密1. 对称加密2. 非对称加密 + 对称加密3. 证书今日摘录 但愿四海无尘沙,有人卖酒仍卖花。 前言 SSL表示安全套接层,是一个用于保护计算机网络中数据传输安全的协议。SSL通过加密来防止第三方恶意截取并篡改数据。在实际应用…

腾讯云标准型S5云主机性能评测_CPU内存_带宽系统盘测评

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CVM 2核2G S5活动优惠价格280.8元一年自带1M带宽&#xff0c;15个月313.2元、2核4G配置748.2元15个月&#xff0c;CPU内存配置还可以选择4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3M、5M或10M&#xff0c;腾…

基于STM32CubeMX和keil采用RTC时钟周期唤醒和闹钟实现LED与BEEP周期开关

文章目录 前言1. RTC概念1.1 RTC的时钟信号源1.2 预分频器1.3 实时时钟与日历数据1.4 周期性自动唤醒1.5 可编程闹钟 2. RTC相关中断3. STM32CubeMX配置3.1 时钟配置3.2 引脚配置3.3 RTC配置3.3.1 模式选择3.3.2 RTC基本参数配置3.3 中断配置 4. 代码编写总结 前言 RTC的功能有…

1.0 Zookeeper 教程

分类 Zookeeper 教程 ZooKeeper 是 Apache 软件基金会的一个软件项目&#xff0c;它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。 ZooKeeper 的架构通过冗余服务实现高可用性。 Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来&…

公网环境固定域名异地远程访问内网BUG管理系统

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…