keilC 中的循环移位
- 格式:docx
- 大小:19.87 KB
- 文档页数:3
头文件INTRINS.H的用法KEIL 中头文件INTRINS.H的作用在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便.内部函数描述_crol_ 字符循环左移_cror_ 字符循环右移_irol_ 整数循环左移_iror_ 整数循环右移_lrol_ 长整数循环左移_lror_ 长整数循环右移_nop_ 空操作8051 NOP 指令_testbit_ 测试并清零位8051 JBC 指令函数名:_crol_,_irol_,_lrol_原型:unsigned char _crol_(unsigned char val,unsigned char n);unsigned int _irol_(unsigned int val,unsigned char n);unsigned int _lrol_(unsigned int val,unsigned char n);举例:_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回_testbit_:相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_:测试并返回源点数状态。
就是汇编中的子函数。
_crol_,_cror_:如果二进制数为01010101 那么_crol_(1) 左移1位后将高位补低位。
结果10101010。
功能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
例:#include <intrins.h>main(){unsigned int y;C-5 1 程序设计37y=0x00ff;y=_irol_(y,4);}函数名:_cror_,_iror_,_lror_原型:unsigned char _cror_(unsigned char val,unsigned char n);unsigned int _iror_(unsigned int val,unsigned char n);unsigned int _lror_(unsigned int val,unsigned char n);功能:_cror_,_iror_,_lror_以位形式将val 右移n 位,该函数与8051“RRA”指令相关,上面几个函数不同于参数类型。
数组循环移位算法要求:设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。
不合题意的解法如下:我们先试验简单的办法,可以每次将数组中的元素右移一位,循环K次。
abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。
版本1void RightShift(char *arr, int N, int k){while(k--){char t = arr[N-1];for(int i = N-1; i > 0; i--)arr[i] = arr[i-1];arr[0] = t;}}虽然这个算法可以实现数组的循环右移,但是算法复杂度为O(K * N),不符合题目的要求,需要继续往下探索。
分析与解法假如数组为abcd1234,循环右移4位的话,我们希望到达的状态是1234abcd。
不妨设K是一个非负的整数,当K为负整数的时候,右移K位,相当于左移(-K)位。
左移和右移在本质上是一样的。
【解法一】大家开始可能会有这样的潜在假设,K<N。
事实上,很多时候也的确是这样的。
但严格地说,我们不能用这样的“惯性思维”来思考问题。
尤其在编程的时候,全面地考虑问题是很重要的,K可能是一个远大于N的整数,在这个时候,上面的解法是需要改进的。
仔细观察循环右移的特点,不难发现:每个元素右移N位后都会回到自己的位置上。
因此,如果K > N,右移K-N之后的数组序列跟右移K位的结果是一样的。
进而可得出一条通用的规律:右移K位之后的情形,跟右移K’=K % N位之后的情形一样。
版本2void RightShift(char *arr, int N, int k){k %= N;while(k--){char t = arr[N-1];for(int i = N-1; i > 0; i--)arr[i] = arr[i-1];arr[0] = t;}}可见,增加考虑循环右移的特点之后,算法复杂度降为O(N2),这跟K无关,与题目的要求又接近了一步。
Keil软件“C语言”与“汇编”混编相关知识整理用Keil在C中嵌入汇编 (1)在Keil中嵌入汇编 (2)介绍直接嵌入汇编代码的方法 (4)采用汇编可能会有的好处 (5)Keil C语言与汇编语言混合编程 (7)深入剖析Keil C51 ——从汇编到C51 (9)C语言和汇编语言的变量以及函数的接口问题 (14)汇编与C语言混合编程的关键问题 (15)KEIL段重定位 (15)用Keil在C中嵌入汇编早前公布了C和汇编混编的温度控制器程序,收到一些朋友的询问,他们无法在自己程序中使用我的18B20的汇编子程序或无法正常通过混编后的程序编译。
其实在KEIL中嵌入汇编的方法很简单。
如图一,在C文件中要嵌入汇编的地方用#pragma asm和#pragma endasm 分隔开来,这样编译时KEIL就知道这中间的一段是汇编了。
图1在有加入汇编的文件中,还要设置编译该文件时的选项图2Generate Assembler SRC File 生成汇编SRC文件Assemble SRC File 封装汇编文件(如图三的状态为选中)选上这两项就可以在C中嵌人汇编了,设置后在文件图示中多了三个红色的小方块。
图3为了能对汇编进行封装还要在项目中加入相应的封装库文件,在笔者的项目中编译模式是小模式所以选用C51S.LIB。
这也是最常用的。
这些库文件是中KEIL安装目录下的LIB目录中。
加好后就可以顺利编译了。
(注:我只在7.0以上版本使用过)图4在Keil中嵌入汇编1、其实在KEIL中嵌入汇编的方法很简单。
如图1,在C文件中要嵌入汇编的地方用#pragma as m和#pragma endasm分隔开来,这样编译时KEIL就知道这中间的一段是汇编了。
2、在有加入汇编的文件中,还要设置编译该文件时的选项,如图2所示。
3、Generate Assembler SRC File 生成汇编SRC文件Assemble SRC File 封装汇编文件(如图3的状态为选中)选上这两项就可以在C中嵌人汇编了,设置后在文件图示中多了三个红色的小方块。
循环移位运算
循环移位运算是指将二进制数的各位按照一定规律向左或向右移动,并将最高位或最低位移到另一侧的运算。
循环左移运算(通常表示为<<)是将二进制数的各位向左移动若干位,并将最高位移到最低位,被移出的位再次从最低位移入最高位。
例如,对于二进制数1010,左移1位后得到二进制数0101。
循环右移运算(通常表示为>>)是将二进制数的各位向右移动若干位,并将最低位移到最高位,被移出的位再次从最高位移入最低位。
例如,对于二进制数1010,右移1位后得到二进制数0101。
循环移位运算在计算机中广泛应用于位运算、密码学等领域。
它可以实现非常高效的数据处理和编码解码操作。
intrins.h在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便.内部函数描述_crol_ 字符循环左移_cror_ 字符循环右移_irol_ 整数循环左移_iror_ 整数循环右移_lrol_ 长整数循环左移_lror_ 长整数循环右移_nop_ 空操作8051 NOP 指令_testbit_ 测试并清零位8051 JBC 指令函数名: _crol_,_irol_,_lrol_原 型: unsigned char _crol_(unsigned char val,unsigned char n);unsigned int _irol_(unsigned int val,unsigned char n);unsigned int _lrol_(unsigned int val,unsigned char n);举例:_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回_testbit_: 相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_: 测试并返回源点数状态。
就是汇编中的子函数。
_crol_,_cror_:如国二进制数为01010101 那么_crol_(1) 左移1位后将高位补低位。
结果10101010。
功 能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
例:#include <intrins.h>main(){unsigned int y;C-5 1 程序设计 37y=0x00ff;y=_irol_(y,4);}函数名: _cror_,_iror_,_lror_原 型: unsigned char _cror_(unsigned char val,unsigned char n);unsigned int _iror_(unsigned int val,unsigned char n);unsigned int _lror_(unsigned int val,unsigned char n);功 能:_cror_,_iror_,_lror_以位形式将val 右移n 位,该函数与8051“RRA”指令相关,上面几个函数不同于参数类型。
c51单片机的循环左移函数 _crol_ 源码1. 背景介绍c51单片机是一种广泛应用于嵌入式系统的微控制器,它采用的是哈佛结构的指令集架构,因此在开发过程中需要编写大量的汇编语言代码。
在c51单片机中,循环左移函数_crol_是一个非常常用的函数,它可以实现对一个字节或字的循环左移操作,是嵌入式系统开发中的基础函数之一。
2. 循环左移函数_crol_的功能循环左移函数_crol_的功能是将一个字节或字进行左移操作,并且在移动的过程中将最高位移到最低位,其他位依次向高位移动。
对于一个8位的二进制数xxx,经过一次循环左移后,变成xxx。
3. _crol_函数的源码在c51单片机中,_crol_函数的源码通常以汇编语言的形式编写,下面是一个常见的_crol_函数源码示例:```assembly_crol:mov a, r0 ; 将需要左移的字节或字存入累加器arlc a ; 累加器a的内容左移一位,并将最高位的值存入CY(进位标志位)mov r0, a ; 将左移后的结果存入r0ret ; 函数返回```4. _crol_函数源码解析以上是一个简单的_crol_函数的源码示例,下面对其进行解析:- 将需要左移的字节或字存入累加器a中;- 使用指令rlc a将累加器a的内容左移一位,并且最高位的值存入CY (进位标志位)中;- 将左移后的结果存入r0中;- 函数返回。
5. _crol_函数源码的优化上述的_crol_函数源码虽然可以实现循环左移的功能,但是在性能和效率上并不是最优的。
下面是对_crol_函数源码的一些优化建议:- 如果在c51单片机的开发中需要频繁使用循环左移操作,可以考虑将_crol_函数的源码嵌入到其他函数中,以减少函数调用的开销;- 通过使用位操作指令,可以进一步提高_crol_函数的执行效率,例如使用指令“rl a”来代替“rlc a”。
6. 总结在c51单片机的开发中,循环左移函数_crol_是一个非常基础且常用的函数,它可以帮助开发者实现对字节或字的循环左移操作。
标题:探寻Keil中的while i--用法在Keil软件中,while循环是一种常见的控制结构,而i--则是一个常见的自减运算符。
那么,将这两者结合在一起,会有怎样的用法和效果呢?本文将从多个角度展开,深入探讨Keil中的while i--用法,并共享个人观点和理解。
让我们一起探索这一主题。
1. 基础概念在编程中,while循环是一种用于重复执行一段代码块的控制结构。
而i--代表的是自减操作,即每次循环结束后,变量i的值减少1。
将这两者组合在一起,while i--即表示每次循环结束后,自动减少i的值并继续循环,直到满足某个条件为止。
2. 用法示例在Keil中,我们可以通过以下示例代码来演示while i--的用法:```cint i = 10;while (i--) {printf("The value of i is %d\n", i);}```在这个示例中,我们初始化了变量i的值为10,然后通过while i--循环,每次循环都会先打印i的值,然后将i减少1。
直到i的值为0时,循环停止。
3. 深入解析通过以上示例,我们可以看到while i--的用法相对简单直观。
但是,如果我们希望对其进行更深入的理解,就需要考虑更多的因素,比如循环条件、自减操作的顺序、代码执行过程等。
在实际开发中,我们还需要考虑边界条件、循环次数、效率等因素。
4. 个人观点和理解对于while i--的用法,我个人认为在某些场景下可以带来便利和效果。
比如在需要逆序遍历数组或列表时,利用while i--可以简洁地实现。
我们也要注意控制循环的条件和边界,以避免出现意外的结果或死循环的情况。
总结回顾通过本文的探讨,我们对Keil中的while i--用法有了更清晰的认识。
无论是基础概念、用法示例,还是深入解析和个人观点,我们都对这一主题有了全面的了解。
在实际应用中,我们可以根据具体场景和需求,灵活运用while i--,从而提高代码的效率和可读性。
一:C语言实现循环移位:
比如将a=0x45循环左移二位。a循环左移n位,即将原来右面(8-n)位左移n位,
而将原来左端的n位移到最右面n位。
实现步骤:
1、将a的左端n位先放到b中的高n位中
b=>>(8-n);
2、将a左移n位,其右面高n位被补0
c=<
3、将b,c进行或运算
a=c|b;
程序如下:
main()
{
unsigned char a=0x45,b,c;
unsigned int n=2;
b=a>>8-n)
c=a<
}
二:Keil C言实现循环移位
在Keil C51中有这样一个库,其头文件为
下几个操作,它不是函数,但象函数,它们有入口出口,但是,没有返回RET
语句,如果有这些操作,用disassembly窗口可以看到是将代码直接嵌入到你的
代码中,其效率很高,比如一个空操作,_nop_() 嵌入的代码就是一个NOP
指令。 在这个库中,有如下操作:
unsigned char _chkfloat_(float val) 检查浮点数状态
返回值:0: standard floating-point numbers
1: Floating-point value 0
2:+INF (positive overflow)
3:-INF (Not a number) error status
unsigned char _crol_( //字节的多次循环左移
unsigned char c, //C左移的字符
unsigned char b);//b左移的位数
unsigned char _cror_( //字节的多次循环右移
unsigned char c, //C右移的字符
unsigned char b);//b右左移的位数
unsigned int _irol_ ( //字的循环左移
unsigned int c, //c左移的字
unsigned char b);//b左移的次数
unsigned int _iror_ ( //字的循环右移
unsigned int c, //c右移的字
unsigned char b);//b右移的次数
unsigned long _lrol_ ( //4字节(双字)的循环左移
unsigned long c,//c左移的双字
unsigned char b);//b左移的次数
unsigned long _lror_ ( //4字节(双字)的循环右移
unsigned long c,//c右移的双字
unsigned char b);//b右移的次数
void _nop_ (void); //NOP 8051中的空操作
bit _testbit_ (bit b);//8051中的JBC指令,测试b,然后清0,返回b
的值。
单片机c语言中的左移右移
左移
变量1 << 变量2
将变量1的二进制位值向左移动由变量2所指定的位数。
例如:
a = 0x8f; // 10001111
a << 2; // 左端移出的值丢弃,右端补0
结果:a = 0x3c (00111100)
在keil c51中,内部函数库INTRINS.H中_crol_(m,n)表示将m循环左移n位,
与m<
变量1 >> 变量2
将变量1的二进制位值向右移动由变量2所指定的位数。
例1:
unsigned char a;
a = 0x8f; // 10001111
a >> 2; // 右端移出的值丢弃,左端补0
结果:a = 0x23 (00100011)
例2:
char a;
a = 0x8f; // 10001111
a >> 2; // 右端移出的值丢弃,左端补入原来的符号位
// 据说有些编译器采用逻辑右移,即左端补0
结果:a = 0xe3 (11100011)