C语言中没有提供循环移位的操作符,但可以通过简洁的方式实现循环移位

设一个操作数x有s位则循环左移n位的操作为:

(x << n) | (x >> (s - n));

同理右移n位位:

(x >> n) | (x << (s - n));

实际编程中可以用宏定义实现循环移位:

#define ROTATE_LEFT(x, s, n) ((x) << (n)) | ((x) >> ((s) - (n)))

#define ROTATE_RIGHT(x, s, n) ((x) >> (n)) | ((x) << ((s) - (n)))

例如:

#include <stdio.h>

#define ROTATE_LEFT(x, s, n) ((x) << (n)) | ((x) >> ((s) - (n)))

#define ROTATE_RIGHT(x, s, n) ((x) >> (n)) | ((x) << ((s) - (n)))

int main()

{

unsigned int a;

scanf("%x", &a);

printf("%08x\n", a);

printf("%08x\n", ROTATE_LEFT(a, 8 * sizeof(int), 4));

printf("%08x\n", ROTATE_RIGHT(a, 8 * sizeof(int), 8));

return 0;

}

运行结果:

12345678 //原数

23456781 //移1位后

具体样例:

设有数据  a=01111011,循环左移2位 正确结果: 11101101

 分步实现:

b=a>>(8-2) ;//用来得到正常左移丢失的位和循环移位后其正确位置 b="00000001";

a="a"<<2;//左移 a="11101100"

a=a|b; //a=11101101

 如果不是用中间变量一步实现: a=(a>>(8-2))|(a<<2);

 总长度N(8 16 32)

 循环左移n (a>>(N-n))|(a>>n)

 循环右移n (a<<(N-n))|(a>>n)

 C语言的位运算功能是其区别于其他大多数高级程序设计语言的特色之一,用它可以方便实现一些特殊功能,灵活掌握是用C程序编写系统程序的基础。

其他对位进行操作的还有位域法;

几个对位操作的样例如下:

#define SETBIT(REG,N) REG|=(1<<N) //对REG的N位置1

#define CLRBIT(REG,N) REG&=~(1<<N) //对REG的N位清零

#define INVBIT(REG,N) REG^=(1<<N) //对REG的N位取反

===================================================================================================================================

我们在C语言中常常碰到字符串循环左右移位的题型,下面对其进行详解:



例如:有一组char的字符串:abcdefghijk 。你要循环左移3位变成ijkabcdefgh(也有写出ijkabcdefghi);或右移三位变成defghijkabc(也有写成cdefghijkabc);



首先我们来解决字符串循环右移的问题:



方法一:利用已有的字符串函数。



#include<stdio.h>



#include<string.h>

void rightloop(char *a, int n);

main()

{

char a[100]; int n;

printf("请输入要循环的字符串:/n");

scanf("%s",a);

printf("请输入要循环字符串的位数:/n");

scanf("%d",&n); //以上代码也可以直接赋初值,我考虑的是一般情况//

void rightloop(a,n); //本例以a[]="abcdefghijk", n=3为例讲解//

printf("输出循环右移的字符串:%s/n",a);

}

void rightloop(char *a, int n)

{

char b[100]; //数组b要做的够大即可//

int m;

m=strlen(a)-n; //求出除去要循环右移之后剩下的字符的个数//

strcpy(b,a+n); // a+n,a代表a[0]的地址再加上n,表示要把a[n]之后的字符串(即那些不用循环右移的字符,共有m个)复制到数组b中。这时b[]="defghijk"。 //

strcpy(b+m,a); // b+m, 因为上面已经把没有循环的m个字符赋给了b,所以b[m]之前的不能在赋值了,只能把a的全部字符串赋给b[m]之后的空间了。这时b[]="defghijkabcdefghijk"。//

*(b+strlen(a))='/0'; //这里是问题的关键,要根据a字符串的长度来舍弃b数组中多余的字符串,并给数 组b加结束符。这时b[]="defghijkabc";//

strcpy(a,b); //把数组b中调整好的字符串重新赋给数组a。//

}

方法二:就是用简单的c语句;

#include<stdio.h>

void rightloop(char , int )

main()

{

char a[100]; int n;

printf("请输入要循环的字符串:/n");

scanf("%s",a);

printf("请输入要循环字符串的位数:/n");

scanf("%d",&n); //以上代码也可以直接赋初值,我考虑的是一般情况//

void rightloop(a,n); //本例以a[]="abcdefghijk", n=3为例讲解//

printf("输出循环右移的字符串:%s/n",a);

}

void rightloop(char a[ ], int n)

{

int i=0,j=0,k=0;

int m; char b[100];

while(a[i]!='/0')

{ i++; } //这里用i来计算数组a中字符串的大小;//

while(a[n]!='/0')

{

b[j]=a[n]; j++; n++;

} //这里是把不需要循环右移的字符串赋值到数组b中;b[ ]="defghijk"。//

while(a[k]!='/0')

{

b[j]=a[k]; j++; k++;

} //因为上一个while循环中,数组b已经赋值到b[j]了。所以这里直接从b[j]开始把数组a中的字符串全部赋值到数组b[j]以后的空间中;b [ ]="defghijkabcdefghijk";//

b[i]='/0'; //通过用数组a中字符串的长度i来调整数组b的长度,删去数组b中多余的字符串 ,b[]="defghijklabc"。

for(i=0;b[i]!='/0';i++)



{ a[i]=b[i]; } //把数组b中调整好的字符串重新赋给数组a。//



}

再次我们来解决字符串循环左移的问题

方法一:调用已经有的字符串函数。

#include<stdio.h>

#include<string.h>

void leftloop(char *a, int n);

main()

{

char a[100]; int n;

printf("请输入要循环的字符串:/n");

scanf("%s",a);

printf("请输入要循环字符串的位数:/n");

scanf("%d",&n); //以上代码也可以直接赋初值,我考虑的是一般情况//

void leftloop(a,n); //本例以a[]="abcdefghijk", n=3为例讲解//

printf("输出已经循环左移的字符串:%s/n",a);

}

void leftloop(char*a,int n)

{char b[100]; //数组b要做的够大即可//

int m;

m=strlen(a)-n; //求出除去要循环右移之后剩下的字符的个数//

strcpy(b,a+m); // a+m,a代表a[0]的地址再加上m,表示要把a[m]之后的字符串(即那些需要循环左移的字符,共有n个)复制到数组b中。这时b[]="ijk"。 //

strcpy(b+n,a); // b+n, 因为上面已经把需要循环的n个字符赋给了b,所以b[n]之前的不能在赋值了,只能把a的全部字符串赋给b[n]之后的空间了。这时b[]="ijkabcdefghijk"。//

*(b+strlen(a))='/0'; //这里是问题的关键,要根据a字符串的长度来舍弃b数组中多余的字符串,并给数组b加结束符。这时b[]="ijkabcdefgh";//

strcpy(a,b); //把数组b中调整好的字符串重新赋给数组a。//

}

方法二:就是用简单的c语句;#include<stdio.h>

void leftloop(char , int )

main()

{

char a[100]; int n;

printf("请输入要循环的字符串:/n");

scanf("%s",a);

printf("请输入要循环字符串的位数:/n");

scanf("%d",&n); //以上代码也可以直接赋初值,我考虑的是一般情况//

void leftloop(a,n); //本例以a[]="abcdefghijk", n=3为例讲解//

printf("输出已经循环左移的字符串:%s/n",a);



}

void leftloop(char a[ ], int n)

{

int i=0,j=0,k;

int m; char b[100];

while(a[i]!='/0')

{ i++; } //这里用i来计算数组a中字符串的大小;//

k=m=i-n; //计算出前面有多少个字符不用移动//

while(a[k]!='/0')

{

b[j]=a[k]; j++; k++;



} //因为这时k=i-m,a[k]表示需要循环移动的第一个字符,这里是把需要循环右移的字符串赋值到数组b中;b[ ]="ijk"。//

b[j]='/0';

m--;k--; //因为要用m调节下面的循环但是要从0开始所以比实际的多了一次;k--是为了要留着数组a中的结束符,不出现乱码;//

while(m>=0)

{

a[k]=a[m]; m--; k--;



} // 原来a[k]=“abcdefghijk",a[m]="abcdefgh",赋值之后a[k]="abcabcdefgh";//

for(i=0;b[i]!='/0';i++)

{ a[i]=b[i]; } //把数组b中调整好的字符串重新赋给数组a。b[i]="ijk";a[i]="abcabcdefgh"。赋值之后a[i]="j//

}

c语言循环位移(数字,字符串)的更多相关文章

  1. C语言-数字字符串转换成这个字符串对应的数字(十进制、十六进制)

    数字字符串转换成这个字符串对应的数字(十进制.十六进制) (1)数字字符串转换成这个字符串对应的数字(十进制) 要求:这个字符串参数必须包含一个或者多个数字,函数应该把这些数字转换为整数并且返回这个整 ...

  2. C语言中的字符串

    字符串 字符串 用双引号引起来的多个字符. 在C语言中字符串是用’\0’结束的.即每个字符串的最后一个字符是’\0’,但是结束符不显示,仅仅标志该字符串到这儿就结束了. 二.声明字符串 char *s ...

  3. python语言学习8——字符串和编码

    Unicode编码 计算机只能处理数字,如果要处理文本,就必须把文本转化为数字才能处理 有许多编码标准,但是不同的编码标准有时候会混乱,所以Unicode应运而生 Unicode把所有语言统一到一套编 ...

  4. 在js中做数字字符串加0补位,效率分析

    分类: Jquery/YUI/ExtJs 2010-08-30 11:27 2700人阅读 评论(0) 收藏 举报 functiondate算法语言c 通常遇到的一个问题是日期的“1976-02-03 ...

  5. R语言︱文本(字符串)处理与正则表达式

    处理文本是每一种计算机语言都应该具备的功能,但不是每一种语言都侧重于处理文本.R语言是统计的语言,处理文本不是它的强项,perl语言这方面的功能比R不知要强多少倍.幸运的是R语言的可扩展能力很强,DN ...

  6. go语言基础之字符串遍历

    Go的字符串遍历,有两种方式: utf-8遍历 unicode遍历 package main import "fmt" func main() { str := "Hel ...

  7. C语言中格式字符串

    C语言中格式字符串的一般形式为: %[标志][输出最小宽度][.精度][长度]类型, 其中方括号[]中的项为可选项. 一.类型 我们用一定的字符用以表示输出数据的类型,其格式符和意义下表所示: 字符  ...

  8. R语言中的字符串处理函数

    内容概览   尽管R是一门以数值向量和矩阵为核心的统计语言,但字符串有时候也会在数据分析中占到相当大的份量.   R语言是一个擅长处理数据的语言,但是也不可避免的需要处理一些字符串(文本数据).如何高 ...

  9. C语言中以字符串形式输出枚举变量

    C语言中以字符串形式输出枚举变量 摘自:https://blog.csdn.net/haifeilang/article/details/41079255 2014年11月13日 15:17:20 h ...

  10. 在js中做数字字符串补0

    转自(http://blog.csdn.net/aimingoo/article/details/4492592) 通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的 ...

随机推荐

  1. Java类加载器概述

    Java类加载器概述 Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由Java 应用开发人员编写的. 系统提供的类加载器 引导类加载器 它用来加载 Java 的核心库,是用原生 ...

  2. 解决vue项目中遇到父组件的按钮或操作控制重新挂载子组件但是子组件却无效果的情况

    在vue项目中终会遇到需要父组件的按钮或操作控制重新挂载子组件的需求,我在新项目中就遇到这种需求.真实场景是父组件的早,中,晚三个按钮(代表三个时间段)来控制子组件的table表格列的动态加载. 子组 ...

  3. Java(6)流程控制语句中分支结构if与switch

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201528.html 博客主页:https://www.cnblogs.com/testero ...

  4. XiaoXin 13Pro-Hackintosh 小新13pro崇尚极简的黑苹果双系统

    Lenovo XiaoXin-13-Pro-Hackintosh 关键词:Hackintosh XiaoXin EFI Tutorial Lenovo 以下提及的EFI及其他部分文件见github仓库 ...

  5. 初学Python “登录”案例 更新!!

    更新内容:添加了登录次数,如果超过限制的次数,则提示账户被锁定,去某邮箱申请解锁账户! 此次仅把登录系统更新之后源代码放到这里,不在共享源文件在网盘了! 1 ''' 2 登录界面 3 ''' 4 5 ...

  6. SpringCloud-SpringBoot-SpringCloudAlibaba对应版本选择

    一.SpringCloud-SpringBoot 对应的版本选择 SpringCloud官网常规方式只能查看最新的几个版本信息 https://spring.io/projects/spring-cl ...

  7. 合理占用服务器空闲GPU[狗头]

    合理占用服务器GPU资源[狗头] 场景:当你想进行模型训练时,发现GPU全被占用,怎么办? 解决方案1: 在终端输入如下命令:watch -n 设定刷新时间(s) nvidia-smi 然后记起来了回 ...

  8. 简明教程 | Docker篇 · 其一:基础入门

    了解Docker Docker是什么 Docker是指容器化技术,用于支持创建和使用 Linux 容器,同时Docker也是软件容器平台. 什么是容器(container) 容器是主机上与其他进程隔离 ...

  9. 线路由器频段带宽是是20M好还是40M好

    无线路由器频段带宽还是40M好. 40M的信号强,速度快.   1.20MHz在11n的情况下能达到144Mbps带宽.穿透性不错.传输距离较远 40MHz在11n的情况下能达到300Mbps带宽.穿 ...

  10. jdk8下载与安装教程

     jdk8下载与安装教程下载有两种方式 一.网盘下载网盘下载链接 pan.baidu.com/s/1VQAwHS6WDjemDnKDnPIvww 提取码:f5tv二.官网下载如果想自己一步步研究亲自实 ...