字符串函数strlen的用法详解及其相关题目

strlne函数的使用

  • 一.strlen函数的声明
  • 二.strlen函数的头文件
  • 三.相关题目
    • 代码1
    • 代码2
    • 题目1
    • 题目2
    • 题目3
    • 题目4
    • 题目5
    • 题目6

一.strlen函数的声明

size_t strlen ( const char * str );

二.strlen函数的头文件

使用strlen函数我们需要使用以下头文件

#include <string.h>

三.相关题目

下面我们来看几段代码

代码1

int main()
{const char* p = "abcdefghi";printf("%lld\n", strlen(p));printf("%lld\n", strlen(p + 1));printf("%lld\n", strlen(p[0]));printf("%lld\n", strlen(&p));printf("%lld\n", strlen(&p + 1));printf("%lld\n", strlen(&p[0] + 1));return 0;
}

首先我们先看运行结果:
在这里插入图片描述

首先解释strlen(p):字符串中有’\0’,而p中存放的是a的地址,所以值就是9
strlen(p + 1):是第一个字符的地址+1,就是第二个字符b,所以就是8
strlen(*p):把a的值传给strlen所以错误
strlen(p[0]):*p == *(p+0) == p[0]错误
strlen(&p):&p是p的地址,从p所占的空间位置开始查找,所以是随机值
strlen(&p + 1):&p是p的地址,&p + 1是p的地址+1,所以是随机值
strlen(&p[0] + 1):&p[0]是第一个元素的地址就是a,向后面找到’\0’前,就是8

代码2

int main()
{int a[3][4] = { 0 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a[0][0]));printf("%d\n", sizeof(a[0]));printf("%d\n", sizeof(a[0] + 1));printf("%d\n", sizeof(*(a[0] + 1)));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(*(a + 1)));printf("%d\n", sizeof(a[1]));printf("%d\n", sizeof(&a[0] + 1));printf("%d\n", sizeof(*(&a[0] + 1)));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a[3]));return 0;
}

首先看运行结果
在这里插入图片描述

这里解释上面代码:

sizeof(a):计算的是整个二维数组地址的大小,一共有十二个元素,每个元素是整型占用4个字节的内存,所以结果就是48
sizeof(a[0][0]):a[0][0]是第一行的第一个元素,大小是4个字节
sizeof(a[0]):a[0]就是第一行的大小,第一行·的数组名单独放在sizeof内部,计算的就是第一行的元素大小就是16(sizeof操作符在之前的博客中也有介绍,感兴趣的小伙伴可以点击主页了解)
sizeof(a[0] + 1):a[0]是第一行数组的数组名,但是数组名不是单独放在sizeof内部,所以数组名表示首元素的地址也就是a[0][0]的地址,a[0]+1就是第一行第二个元素a[0][1]的地址,地址的大小就是4或者8个字节
sizeof(*(a[0] + 1)):a[0] + 1是第一行第二个元素(a[0][1])的地址,(a[0] + 1)就是第一行第二个元素,大小是4个字节
sizeof(a + 1):a没有单独放在sizeof内部。+1就是第一行的地址,第一行有4个元素,所以大小是16个字节
sizeof(a[1]):等价于sizeof(
(a+1)),也是第一行的地址,16个字节
sizeof(&a[0] + 1):a[0]是第一行的地址,&a[0] + 1就是第二行的地址,4或者8个字节
sizeof(*(&a[0] + 1)):&a[0] + 1就是第二行的地址,第二行有4个元素,所以就是16个字节
sizeof(*a):数组名a就是数组首元素地址,就是第一行的地址*a就是第一行的地址(*a == *(a+0) == a[0])所以就是16个字节
sizeof(a[3]):是第四行的地址,所以就是16个字节

题目1


int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1);printf("%d, %d", *(a + 1), *(ptr - 1));return 0;
}

首先看一下运行结果
在这里插入图片描述

这里解释(int*)(&a + 1):&a是数组的地址,在+1就是跳过整个数组
*(a + 1):a是首元素地址,+1就是第二个元素地址,在解引用就是2
*(ptr - 1):ptr是数组的地址,在-1就是第五个元素,就是5
在这里插入图片描述

题目2

在X86环境下
假设结构体的⼤⼩是20个字节
程序输出的结构是啥?
指针运算中的指针±整数

struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
} * p = (struct Test*)0x100000;int main()
{printf("%p\n", p + 0x1);printf("%p\n", (unsigned long)p + 0x1);printf("%p\n", (unsigned int*)p + 0x1);return 0;
}

p + 0x1:0x1是十六进制里面的1,十六进制的1和十进制里的1是一样的,所以就是0x00100014
unsigned long:是整型,整形加减就是整型,所以就是+1结果就是0x00100001
(unsigned int*)p:是整型指针,整型指针+1就是4个字节,所以结果就是0x00100004

题目3

int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5)}; int* p;p = a[0];printf("%d", p[0]);return 0;
}

int a[3][2] = { (0, 1), (2, 3), (4, 5)}; :数组内是逗号表达式,所以值是1,3,5
此时数组内的元素就是在这里插入图片描述
p[0]:等价于*(p+0),就是第一个元素,就是1

下面是运行结果:
在这里插入图片描述

题目4

假设环境是x86环境,程序输出的结果是啥?

int main()
{int a[5][5];int(*p)[4];p = a;printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}

p[4][2]a[4][2]之间相差4个元素,但是p[4][2]是小地址,a[4][2]是大地址,所以结果是复数如下图
在这里插入图片描述

printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); :这段代码,第一是以%p的方式打印,-4要存在内存当中存的是补码,地址没有原反补的概念所以直接打印F F F F F F F C,但是以%d的方式打印存的就是源码

-4的
源码:10000000 00000000 00000000 00000100
反码:111111111 111111111 111111111 11111101
补码:111111111 111111111 111111111 11111110
换成十六进制就是
F F F F F F F C

运行结果:
在这里插入图片描述

题目5

int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* ptr1 = (int*)(&aa + 1);int* ptr2 = (int*)(*(aa + 1));printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10  5return 0;
}

&aa + 1:&aa是数组名,数组名+1就是跳过整个数组,所以*(ptr1 - 1)就是10,如下图:

在这里插入图片描述

*(aa + 1):aa是数组首元素地址,+1就是第二行地址,*(aa+1)等价于aa[1],就是5,如下图
在这里插入图片描述

下面代码的运行结果是

在这里插入图片描述

题目6

int main()
{const char* a[] = { "work","at","alibaba" };const char** pa = a;pa++;printf("%s\n", *pa);return 0;
}

a是首元素地址,所以pa就是第一个元素地址,
pa++就是第二个元素地址,在解引用拿到第二个元素,如下图:

在这里插入图片描述

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

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

相关文章

Powercli常用命令

背景 vcenter web界面不如命令行快&#xff0c;且不能批量操作。 根据实际需求逐步补充使用到的powercli 命令。 00 通过bat脚本配置terminal标签页 在WindowsTerminal上配置新的标签页&#xff0c;实现打开标签页即默认连接vcenter。 脚本内容如下&#xff1a; echo off p…

Unity中C#使用协程控制Shader材质变化

文章目录 前言一、协程是什么二、在Unity中使用协程1、我们在 Start 中测试一下协程的执行顺序2、我们实现一个点击按钮实现角色受击效果 三、协程中的动画过渡1、首先&#xff0c;在协程内实现中毒并且消散的效果2、在 OnGUI 内&#xff0c;给一个新按钮使用刚刚定义的协程 四…

STM32通用定时器

本文实践&#xff1a;实现通过TIM14_CH1输出PWM&#xff0c;外部显示为呼吸灯。 通用定时器简介 拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器&#xff0c;具有4路独立通道&#xff0c;可用于输入捕获、输出比 较&#xff0c;同时包含了基本定时去的所有功能。 通用定时器的结…

深入分析爬虫中time.sleep和Request的并发影响

背景介绍 在编写Python爬虫程序时&#xff0c;我们经常会遇到需要控制爬取速度以及处理并发请求的情况。本文将深入探讨Python爬虫中使用time.sleep()和请求对象时可能出现的并发影响&#xff0c;并提供解决方案。 time.sleep()介绍 首先&#xff0c;让我们来了解一下time.s…

前端——html拖拽原理

文章目录 ⭐前言⭐draggable属性&#x1f496; api&#x1f496; 单向拖动示例&#x1f496; 双向拖动示例 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端——html拖拽原理。 vue3系列相关文章&#xff1a; vue3 fastapi 实现选择目录所有文…

根据已有安装的cuda配置合适的pytorch环境

目前网络上根据电脑配置安装合适的深度学习环境的帖子已经很多了&#xff0c;但是现实中会出现很久之前已经安装了对应的cuda&#xff0c;但是现在忘记了当时安装的是什么版本。本文针对这一问题展开攻略。 1 cuda安装版本查询 我们在查询自己应该安装什么版本的cuda时&#…

【模电】直流通路与交流通路

直流通路与交流通路 通常&#xff0c;在放大电路中&#xff0c;直流电源的作用和交流信号的作用总是共存的&#xff0c;即静态电流、电压和动态电流、电压总是共存的。但是由于电容、电感等电抗元件的存在&#xff0c;直流量所流经的通路与交流信号所流经的通路不完全相同。因此…

【设计模式】职责链模式设计在线文档帮助系统

职责链模式设计在线文档帮助系统 任务三&#xff1a;使用职责链模式设计在线文档帮助系统 某公司欲开发一个软件系统的在线文档帮助系统&#xff0c;用户可以在任何一个查询环境中输入查询关键字&#xff0c;如果当前查询环境下没有相关内容&#xff0c;则系统会将查询按照一定…

获取Spring容器Bean工具类

获取Spring容器Bean工具类 1、创建SpringUtils工具类2、注册 SpringUtils工具类3、如果打包的是War方式&#xff0c;可能上面两个注册工具类的方法都没用 1、创建SpringUtils工具类 public class SpringUtils implements ApplicationContextAware {private static Application…

【鸿蒙应用开发】开发环境搭建及IDE安装使用

1.下载安装包 安装包下载地址&#xff1a; 点击跳转下载页面 可以根据自己的操作系统选择对应版本下载。 本文以Windows安装为例&#xff0c;Mac安装方式相同 2. 安装 下载好后&#xff0c;打开安装包&#xff0c;进入安装界面&#xff1a; 点击Next&#xff0c;进入安…

【Vue】使用 Vue CLI 脚手架创建 Vue 项目(使用命令行创建)

前言 在开始使用Vue进行开发之前&#xff0c;我们需要先创建一个Vue项目。Vue CLI&#xff08;Command Line Interface&#xff09;是一个官方提供的脚手架工具&#xff0c;可以帮助我们快速创建Vue项目。 步骤 打开终端或命令行工具&#xff0c;运行以下命令&#xff1a; vu…

蔚碳科技联合中投会发布国内首个 ESG 尽职调查服务标准

11 月 26 日&#xff0c;蔚碳&#xff08;上海&#xff09;科技有限公司&#xff08;以下简称“蔚碳科技”&#xff09;受邀出席由深圳市人民政府主办&#xff0c;深圳市发展和改革委员会、深圳市生态环境局、龙岗区人民政府共同承办的 2023 碳达峰碳中和论坛暨深圳国际低碳城论…

手机升级到iOS15.8后无法在xcode(14.2)上真机调试

之前手机是iOS14.2的系统,在xcode上进行真机测试运行良好&#xff0c;因为想要使用Xcode的Instruments功能&#xff0c;今天将系统更新到了iOS15.8 &#xff0c;结果崩了 说是Xcode和手机系统不兼容不能进行真机测试。在网上查不好些方法&#xff0c;靠谱的就是下载相关版本的…

05、pytest断言确定的异常

官方用例 # content of test_sysexit.py import pytestdef f():raise SystemExit(1)def test_mytest():with pytest.raises(SystemExit):f()解读与实操 ​ 标准python raise函数可产生异常。pytest.raises可以断言某个异常会发现。异常发生了&#xff0c;用例执行成功&#x…

常见的几种计算机编码格式

前言&#xff1a; 计算机编码是指将字符、数字和符号等信息转换为计算机可识别的二进制数的过程&#xff0c;正因如此&#xff0c;计算机才能识别中英文等各类字符。计算机中有多种编码格式用于表示和存储文本、字符和数据&#xff0c;实际走到最后都是二进制&#xff0c;本质一…

CefSharp 获取POST(AJAX)、GET消息返回值(request)

CefSharp作为专门为爬虫工具开发的库比Selenium这种开发目的是页面测试工具然后用来做爬虫的工具要贴心得多。我们操作网页的时候发送或者做了某个动作提交表单之后需要知道我们的动作或者提交是否成功&#xff0c;因为有的页面会因为网络延迟问题提交失败&#xff0c;需要准确…

VIVADO-FFT IP核学习记录

根据用户手册使用IP核 ① 找到user guide / product guide 并打开 ② 找到Customizing and Generating the Core(不同手册可能题目不一样)&#xff0c;查看IP核的创建过程中各个参数的意义和设置方法。 ③ 找到port description &#xff0c;查看接口注释 根据网络教程使用…

微信小程序调用相机拍摄或手机相册

wx.chooseMedia(Object object) 功能描述 拍摄或从手机相册中选择图片或视频。

Facebook推广工具功能科普!

随着社交媒体的普及&#xff0c;Facebook已经成为全球使用最广泛的社交平台之一&#xff0c;对于广大营销人员来说&#xff0c;利用Facebook推广工具进行营销已经成为不可或缺的一部分。 那么&#xff0c;这些推广工具到底有哪些功能呢?本文将为您揭秘Facebook推广工具的强大…

SaToken利用Redis做持久化

官网解释 官网解释 教程 引入依赖 <!-- 提供Redis连接池 --> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId> </dependency><!-- Sa-Token 整合 Redis &#xff08;使用 jdk 默认序…