字符串逆序的几种写法

article/2025/10/24 21:44:07

字符串逆序的几种写法

提示:将字符串逆序与将其逆序打印出来是两码事,逆序是将内容倒着改变了,逆序打印虽然打印结果也是倒着的,不过储存字符串的数组内容并没有改变。

一、非递归写法

1. 将一个给定的字符串abcdef逆序

#include <stdio.h>
int main()
{char arr[] = "abcdef";int sz = sizeof(arr) / sizeof(arr[0]); //求的是数组包含的元素个数,'\0'也包括在内int left = 0;int right = sz - 2;   //减2是因为求得的sz包含了'\0'这个元素。while (left < right){char tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}printf("%s", arr);return 0;
}

打印结果为fedcba。
逆序思路为:将一字符串最左端与最右端的字符交换,交换过后,通过数组下标将左边第二个字符与右边第二个字符交换,依次类推,知道数组下标通过left++与right–,使得left>=right。
在这里插入图片描述

2. 自己输入一串字符串,将其逆序

#include <stdio.h>
#include <string.h>
int main()
{char arr[101] = { 0 };     //要给字符数组一定的内存大小,如果写成char arr[] = { 0 };,当在给数组输入的时候就会造成越界访问。scanf("%s", arr);int sz = strlen(arr);    //在给定字符数组的大小为101的情况下,只能用strlen求输入字符串长度。//用sizeof(arr)/sizeof(arr[0])求出来的是数组大小,为101。int left = 0;int right = sz - 1;while (left < right){char tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}printf("%s", arr);return 0;
}

随便输入一串字符,例如:12345gf,打印结果为fg54321。
注意:对于自己给数组输入数据,再将其逆序这种情况下,在定义数组时,要给字符数组一定的内存大小。如果写成char arr[] = { 0 };,说明这个数组的容量只有一个字节,只能输入一个字符,当在给数组输入的时候就会造成越界访问。

3. 将逆序封装成函数

#include <stdio.h>
#include <string.h>
void reverse(char arr[])
{int left = 0;int right = strlen(arr) - 1;      //封装成函数只能用库函数求字符串长度,不能用sizeof(arr)/sizeof(arr[0])-1这种方式。//因为数组形参就是个地址。sizeof(arr)与sizeof(arr[0])的大小都是四个字节或者八个字节。while (left < right){char tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}
}
int main()
{char arr[] = "abcdef";reverse(arr);printf("%s", arr);return 0;
}

与sizeof 两者用来求字符串长度时的场合区别。
这里值得注意的是,在自定义函数中求字符串长度时,不要用sizeof(arr)/sizeof(arr[0])-1这种方式。直接使用库函数 strlen。因为数组在传参的时候,传过去的是数组首元素的地址,也就是说形参虽说写的是数组的形式char arr[],但是形参其实是个指针变量char*。对于指针变量来说,其大小根据编译器环境,都是四个字节或者都是八个字节。sizeof运算符就是获取数据类型和表达式的尺寸的(单位:字节)。sizeof(arr)与sizeof(arr[0])的大小都是四个字节或者八个字节。所以sizeof(arr)/sizeof(arr[0])-1=4/4-1=0,或者8/8-1=0。

二、递归写法

1. 方法一

#include <stdio.h>
#include <string.h>
void reverse(char str[])  //用数组接收实参,也可用指针接收实参,如void reverse(char* str) 
{char tmp = *str;int len = strlen(str);*str = *(str + len - 1);*(str + len - 1) = '\0';if (strlen(str + 1) >= 2)  //首尾交换后,剩下的元素构成的数组,长度要大于1,才逆序,只剩下一个元素,表明其是最中间的元素,放在原位就好。{reverse(str + 1);}*(str + len - 1) = tmp;
}
int main()
{char arr[101] = { 0 };scanf("%s", arr);reverse(arr);printf("%s\n", arr);return 0;
}

思路:假设一个数组有 n 个元素。
交换str[0]与 str[n-1],再逆序 str[1] 与 str[n-2]
交换 str[1] 与 str[n-2],再逆序 str[2] 与 str[n-3]。依次类推
······
操作步骤:1.先将第一个字符,即 str[0] 位置上的字符放在一个临时变量中。2.将最后一个元素交换到 str[0] 的位置去。3.将字符串中的’\0’放到arr[n-1] 的位置上去。4.此时从 str[1] 到 str[n-2] 的角度上看,是一个新的字符串,将 str[1] 与 str[n-2] 交换。5.将先前放在临时变量中的第一个字符赋给 arr[n-1] 的位置上去。

注意:在第三步并没有将放在临时变量中的第一个字符直接往 str[n-1]上放,而是经过第四步,将str[1] 与 str[n-2] 交换后,才将之前未交换完的第一个字符放到 str[n-1] 上去。原因:如果直接将 str[0] 与 str[n-1] 上的元素通过一个临时变量交换了。那么对于即将要交换的 str[1] 与 str[n-2] 来说,他们与’\0’之间隔了一个放在str[n-1]上的第一个字符,str[1] 与 str[n-2] 也就无法通过首尾字符直接交换的方式进行交换了 。

在这里插入图片描述
逆序a b c d e f 等于交换 a与f ,再逆序b c d e
逆序b c d e 等于交换b与e,再逆序c d。依次类推。

2. 方法二

#include <stdio.h>
#include <string.h>
void reverse(char str[], int left, int right)
{if (left < right){char tmp = str[left];str[left] = str[right];str[right] = tmp;reverse(str, left + 1, right - 1);}}
int main()
{char arr[101] = { 0 };scanf("%s", arr);int left = 0;int right = strlen(arr) - 1;reverse(arr, left, right);printf("%s\n", arr);return 0;
}

方法二比方法一传的参数要多,直接将首尾字符通过第三个临时变量进行交换就行。


http://chatgpt.dhexx.cn/article/1EZC2ejh.shtml

相关文章

字符串逆序(递归实现)

目录 一、代码实现&#xff1a; 二、代码逐步实现过程&#xff1a; 1、不用递归用循环方式实现&#xff1a; 1、使用库函数&#xff1a; 2、不使用库函数&#xff1a; &#xff08;1&#xff09;使用参数是数组的形式&#xff1a; &#xff08;2&#xff09;使用参数是指…

【C语言刷题】字符串逆序

目录 一、字符串逆序&#xff08;基础题&#xff09; 1.一个经典的错误&#xff0c;标准的零分 2.采用gets函数来修补漏洞 3.非要使用scanf怎么办&#xff1f; 4.使用指针来实现逆序函数 5.将函数修改为&#xff0c;只要传入两个地址&#xff0c;就能逆序这两个地址之间的…

使用C语言实现字符串逆序操作

这篇文章主要介绍了使用C语言实现字符串逆序操作案例,本文包含使用C语言的两种方法去实现,递归和非递归,以下就是详细内容,需要的朋友可以参考下 编写一个函数 reverse_string(char * string) 实现&#xff1a;将参数字符串中的字符反向排列。 要求&#xff1a;不能使用C函数库…

C语言实现——字符串逆序

目录 前言 如何实现 代码实现 1.设立一个数组存放输入的字符串 2.将输入的字符串整体逆序 2.1 计算字符串长度 2.2 使用函数来实现倒置 2.3 实现函数reverse 3.将其中每个单词再进行逆序 3.1 整个语句如何结束循环 3.2 每个单词的结束位置 3.3 内部实现 3.4 判断…

dtb展开成device_node

dtb展开成device_node 文章目录 dtb展开成device_node设备树是如何传递给内核的&#xff1f;设备树相关结构体举例of操作函数与查找节点有关的 OF 函数1、of_find_node_by_name 函数2、of_find_node_by_type 函数3、of_find_compatible_node 函数4、of_find_matching_node_and_…

设备树之DTS与DTB格式

目录 一、设备树 二、DTS格式 2.1 属性 2.2 节点 2.3 引用其他节点 2.4 小总结 三、DTB格式 3.1 结构 3.2 分析 一、设备树 对于点灯字符设备驱动程序可以有三种写法&#xff0c;首先是传统方法&#xff0c;这种方式直接在程序中写死&#xff0c;其次是利用总线设备驱…

Android boot.img dtb.img 编译过程

最近做RK3588案子,修改dts后,导致boot.img过大,编译出错,整体分析下boot.img过大的原因是因为在打包boot.img过程中,dbt.img过大导致,所以整体分析下boot.img编译过程,尤其是dbt.img的生成过程. boot.img生成过程 在Andorid跟目录下执行, source build/envsetup.sh 然后lunch x…

Linux 设备树(二) dtc dts/dtsi dtb的关系

在学习设备树之前&#xff0c;我们先来了解一下跟设备树相关的三个对象&#xff0c;分别是dtc、dts/dtsi、dtb。 dtc:用来编译设备树的工具 dts:设备树描述文件 dtsi:设备树头文件 dtb:编译后的二进制文件 dtc设备树编译工具 dtc是用来编译设备树的工具&#xff0c;就像gcc可以…

dtb如何转换到platform_device

分2步&#xff0c;第一步是首先转换为device_node&#xff0c;第二步device_node转换为platform_device。 第一步 /*** unflatten_device_tree - create tree of device_nodes from flat blob** unflattens the device-tree passed by the firmware, creating the* tree of st…

U-Boot 之一 零基础编译 U-Boot 过程详解、Image 镜像介绍及使用说明、DTB 文件使用说明

最近&#xff0c;工作重心要从裸机开发转移到嵌入式 Linux 系统开发&#xff0c;在之前的博文 Linux 之八 完整嵌入式 Linux 环境、&#xff08;交叉&#xff09;编译工具链、CPU 体系架构、嵌入式系统构建工具 中详细介绍了嵌入式 Linux 环境&#xff0c;接下来就是实际动手学…

dts、dtb的那些事儿

笔者最近在支持新的案子&#xff0c;过于忙碌&#xff0c;好久没更新了&#xff0c;勿怪。 1、设备树大变革故事 2011年3月17日的ARM Linux邮件列表有封邮件“this whole ARM thing is a fucking pain in the ass”引起了轩然大波&#xff0c;原来是我们的Linux之父Linus Torv…

DBT工具简介

What is DBT 在将数据加载到集中式数据仓库之前&#xff0c;必须对其进行清理、保持一致并根据需要进行组合。换句话说&#xff0c;必须转换数据&#xff0c;这就是我们所谓的 ETL&#xff08;提取、转换、加载&#xff09;和 ELT 中的“T”。 这是挖掘数据价值的关键一步。 而…

4.2uboot对设备树的支持——dtb的修改原理

本节说明在uboot中修改dtb的原理。 在uboot中&#xff0c;有一些命令支持对dtb文件进行修改。 当我们想要修改dtb文件时&#xff0c;可以直接修改dts文件&#xff0c;然后编译dts文件生成新的dtb文件&#xff0c;再将新的dtb文件载入设备。 或者&#xff0c;我们也可以在ubo…

DBT是什么

关于DBT DBT 是一种数据转换工作流&#xff0c;可帮助您完成更多工作&#xff0c;同时产生更高质量的结果。您可以使用 dbt 来模块化和集中分析代码&#xff0c;同时还为数据团队提供软件工程工作流中常见的护栏。在将数据模型安全部署到生产环境之前&#xff0c;通过监控和可见…

2.1设备树的规范(dts和dtb)——DTS格式

本节学习设备树的规范。 使用设备树时&#xff0c;需要编写dts文件&#xff0c;然后使用dtc编译dts文件&#xff0c;生成dtb文件。 所以本节分为两部分&#xff0c;第一部分讲解dts格式&#xff0c;第二部分讲解dtb格式。 首先看一下dts文件的布局。 DTS文件布局&#xff0…

关于EMUELC适配各种机型,DTB如何修改教程

很多爱好者留言&#xff0c;都想问关于EMUELC的dtb适配机型问题&#xff0c;这里我就出一个教程&#xff0c;如何修改dtb&#xff0c;然后去适配自己的机型&#xff0c;然后启动 。这里我只是提供方法&#xff0c;具体的调试是需要原理图进行配置。 首先&#xff0c;不管是aml…

DTBO简介

1、DTBO简介 设备树 (DT) 是用于描述“不可发现”硬件的命名节点和属性构成的一种数据结构。操作系统&#xff08;例如在 Android 中使用的 Linux 内核&#xff09;会使用 DT 来支持 Android 设备使用的各种硬件配置。硬件供应商会提供自己的 DT 源文件&#xff0c;接下来…

【DTB/DTBO 分区介绍】

如果你的 DTB/DTBO 位于专属的分区&#xff08;例如 dtb 和 dtbo 分区&#xff09;中&#xff0c;请使用以下表格结构和头文件格式&#xff1a; 数据结构 dt_table_header 仅适用于 dtb/dtbo 分区&#xff1b;您不能在kernel( image.gz) 末尾处附加此格式。如果您有一个 DTB/D…

2.2设备树的规范(dts和dtb)——DTB格式

本节讲述设备树的dtb格式。 上节讲述了dts格式。回顾上节&#xff0c;在dts文件和dtsi文件中&#xff0c;可以使用C语言的define和include&#xff0c;使用方法和作用也同C语言相同。 编写dts文件后&#xff0c;需要使用dtc工具将dts文件编译成dtb文件。dtc工具可以检查dts文…

「设备树」dtb给内核的两种工作模式

一&#xff0c;传递dtb给内核 对于传统bootloader提供两种工作模式&#xff1a;一是启动加载模式&#xff08;start loading&#xff09;&#xff0c;一是下载模式&#xff08;downloading&#xff09; 工作在启动加载模式时&#xff0c;bootloader会自动执行bootcmd命令&#…