字符串函数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.hqwc.cn/news/247373.html

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

相关文章

景联文科技解读《2023人工智能基础数据服务产业发展白皮书》,助力解决数据标注挑战

前段时间&#xff0c;国家工业信息安全发展研究中心发布《2023人工智能基础数据服务产业发展白皮书》&#xff08;以下简称“白皮书”&#xff09;。 《白皮书》指出&#xff0c;2022年&#xff0c;中国人工智能基础数据服务产业的市场规模为45亿元&#xff0c;预计今年将达到5…

一篇解析context_switch进程切换(针对ARM体系架构)

一. 概述 在最近初学ebpf时&#xff0c;使用到了挂载点finish_task_switch统计内核线程的运行时间&#xff0c;遂进入内核源码对其进行学习分析。 finish_task_switch在context_switch被调用&#xff0c;其功能是完成进程切换的收尾工作&#xff0c;比如地址空间的清理。而co…

pycharm打断点调试

在PyCharm中使用断点调试可以帮助逐行执行代码并查看变量的值&#xff0c;以便更好地理解程序的执行过程。以下是在PyCharm中设置断点和使用调试功能的步骤和注意事项&#xff1a; 步骤&#xff1a; 打开PyCharm并打开要调试的项目。找到要设置断点的代码行。您可以在行号区…

大数据技术学习笔记(四)—— HDFS

目录 1 HDFS 概述1.1 HDFS 背景与定义1.2 HDFS 优缺点1.3 HDFS 组成架构1.4 HDFS 文件块大小 2 HDFS的shell操作2.1 上传2.2 下载2.3 HDFS直接操作 3 HDFS的客户端操作3.1 Windows 环境准备3.2 获取 HDFS 的客户端连接对象3.3 HDFS文件上传3.4 HDFS文件下载3.5 HDFS删除文件和目…

ROS2 galactic生成的bag包里的MarkerArray在humble下播放不正常

近期发现ROS2 galactic下生成的bag包在humble下回放时使用rviz可视化&#xff0c;bag里的点云可以正常看到&#xff0c;但是使用Marker和MarkerArray画的box却死活看不到&#xff0c;感觉很纳闷&#xff0c;看网上有人报告说foxy下生成的bag包在galactic下播放会报SQL错误&…

Oracle 中换行chr(10)、回车chr(13)

一、前言 chr(n)&#xff1a;返回 ascii 值对应的字符。 ascii(char)&#xff1a;返回字符 char对应的ascii 值。 chr(n) 和 ascii(char) 作用刚好是相反的。 SQL> select chr(65) from dual; 控制台显示&#xff1a;ASQL> select ascii(A) from dual; 控制台显示&am…

【C++】开源:Boost进程间通信库InterProcess配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Boost进程间通信库InterProcess配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一…

java--接口概述

1.认识接口 ①java提供了一个关键字interface&#xff0c;用这个关键字我们可以定义出一个特殊的结构&#xff1a;接口。 ②注意&#xff1a;接口不能创建对象&#xff1b;接口是用来被类实现(implements)的&#xff0c;实现接口的类称为实现类。 ③一个类可以实现多个接口(接…

LVS-DR+Keepalived+动静分离实验

架构图 解释一下架构&#xff0c;大概就是用Keepalived实现两台DR服务器的LVS负载均衡&#xff0c;然后后端服务器是两台Nginx服务器两台Tomcat服务器并且实现动静分离这个实验其实就是把 LVS-DRKeepalived 和 动静分离 给拼起来&#xff0c;真的是拼起来&#xff0c;两个部分…

某60区块链安全之JOP实战一学习记录

区块链安全 文章目录 区块链安全Jump Oriented Programming实战一实验目的实验环境实验工具实验原理实验内容Jump Oriented Programming实战一 实验步骤分析合约源代码漏洞Jump Oriented Programming实战一 实验目的 学会使用python3的web3模块 学会分析以太坊智能合约中中Ju…

目标检测——R-CNN系列检测算法总结

R-CNN系列算法详细解读文章&#xff1a; R-CNN算法解读SPPNet算法解读Fast R-CNN算法解读Faster R-CNN算法解读Mask R-CNN算法解读 目录 1、概述1.1 获取目标候选框1.2 候选框提取特征1.3 候选框分类及边框回归 2、R-CNN系列算法概述2.1 R-CNN算法2.2 SPPNet算法2.3 Fast R-CN…

如何将Java条码Dynamsoft Barcode Reader集成到命令行、GUI和Web应用程序中

Dynamsoft Barcode Reader SDK一款多功能的条码读取控件&#xff0c;只需要几行代码就可以将条码读取功能嵌入到Web或桌面应用程序。这可以节省数月的开发时间和成本。能支持多种图像文件格式以及从摄像机或扫描仪获取的DIB格式。使用Dynamsoft Barcode Reader SDK&#xff0c;…