【C语言】宏定义(写一个宏可以将一个数字二进制的奇数位和偶数位交换)

更新时间:2023-07-31 23:47:22 阅读: 评论:0

【C语⾔】宏定义(写⼀个宏可以将⼀个数字⼆进制的奇数位
和偶数位交换)
1.写⼀个宏可以将⼀个数字的奇数位和偶数位交换。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define FSWAP(N) (((N&0X55555555)<<1)|((N&0xaaaaaaaa)>>1))
int main()
{
int n = 0;
printf("请输⼊⼀个数字\n");
潘多拉魔盒scanf("%d",&n);
11playerprintf("%d",FSWAP(n));
return 0;
}
看到这个题⽬的时候我想如何才能将两个数字中的奇数位和偶数位进⾏交换,最初的时候我想的是⽤⼀个数组将数字中的每⼀位存储起来,然后进⾏输出,之后我⼀直在想怎么将这个功能实现到宏定义⾥边,后来想了很多都发现这不可能,所以我百加思索才发现,这⾥的奇数偶数进⾏交换是将他的⼆进制数进⾏的奇数偶数位进⾏交换,既然是对⼆进制进⾏交换了那⼤家⾃然也就想到了按位与按位或这种⼆进制操作,很多⼈纳闷0x55555555这个是个什么,这个实际上就是⼗六进制的10101010101010101010101010101010,就是它,所以开始先将n和它按位与,求出来n的所有偶数位置的数字,然后将求得的数左移⼀位,现在的数字就是将n的奇数位的所有内容放到了偶数位置,这时候只要求出来n的偶数为然后放到奇数位置就可以了,所以先移动n向右移虽然这时候n的32位少了⼀个,但是少的那个是32位的奇数位,所以并不影响,然后将两个求得的数字进⾏或运算,就能将这个数字的32位⼆进制的奇数位和偶数位进⾏交换
2.使⽤宏实现两个数中求较⼤值。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAX(a,b) a>b?a:b
int main()
{
int x = 0;
植物的叶子int y = 0;
printf("请输⼊两个数值\n");
scanf("%d %d", &x, &y);
printf("两个数字中较⼤的是%d", MAX(x, y));
return 0;
}
拓展⼩常识:
使⽤宏,不仅使代码看起来整洁,⽽且⽤好了还能极⼤的减轻编码的⼯作量,但是如果使⽤不当的话,出了问题查找起来就就⾮常的难了 .
宏使⽤中的常见的基础问题
1. 防⽌⼀个头⽂件被重复包含
#ifndef  __GAME_H__
#define __GAME_H__
//头⽂件内容
#endif //__GAME_H__
什么食物含钾最高
2.使⽤⼀些宏跟踪调试
ANSI标准说明了五个预定义的宏名。它们是:
__LINE__ (两个下划线),对应%d
xxx护士
义务兵退伍
__FILE__ 对应%s
__DATE__ 对应%s
__TIME__ 对应%s
__STDC__
如果编译不是标准的,则可能仅⽀持以上宏名中的⼏个,或根本不⽀持。记住编译程序也许还提供其它预定义的宏名。
etc有优惠吗
__LINE__宏指令表⽰当前指令所在的⾏,是个整型数
__FILE__宏指令表⽰当前指令所在⽂件,包含完整路径
__DATE__宏指令含有形式为⽉/⽇/年的串,表⽰源⽂件被翻译到代码时的⽇期。
__TIME__宏指令包含源代码翻译到⽬标代码的时间。串形式为时:分:秒。
如果实现是标准的,则宏__STDC__含有⼗进制常量1。如果它含有任何其它数,则实现是⾮标准的  //  VS 不是标准  gcc 标准。
可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在⽂件所在⾏
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf("%d%d%s",date,_LINE_,_FILE_)
#el
#define DEBUGMSG(msg,date)
#endif
3.宏中"#"和"##"的⽤法
在C语⾔的宏中,#的功能是将其后⾯的宏参数进⾏字符串化操作(Stringfication),简单说就是在对它所引⽤的宏变量通过替换后在其左右各加上⼀个双引号。⽽##被称为连接符(concatenator),⽤来将两个Token连接为⼀个Token.注意这⾥连接的对象是Token就⾏,⽽不⼀定是宏的变量。
我们使⽤#把宏参数变为⼀个字符串,#@把参数变为字符,⽤##把两个宏参数贴合在⼀起。
#define  fun(dst, str)  strcpy(dst, #str)
//fun(buff,abc) 相当于 strcpy(buff,“abc”)
#define fun(arg)    my##arg
//fun(ABC)  相当于 myABC
#define fun(a,b)    a=#@b
//fun(x,y) 相当于 x='y'
前⽅⾼能:<;宏&&宏函数&&函数>区别
宏和函数的区别:
1. 宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),⽽函数的参数的传递,参数是有数据类型的,可以是各种各样的类型.
2. 宏的参数替换是不经计算⽽直接处理的,⽽函数调⽤是将实参的值传递给形参,既然说是值,⾃然是计算得来的.宏不⽀持递归,函数可以,宏不⽀持调试,函数可以.宏对于(++、--)可能会产⽣副作⽤,
函数不会.
3. 宏在编译之前进⾏,即先⽤宏体替换宏名,然后再编译的,⽽函数显然是编译之后,在执⾏时,才调⽤的.因此,宏占⽤的是编译的时间,⽽函数占⽤的是执⾏时的时间.
4. 宏的参数是不占内存空间的,因为只是做字符串的替换,⽽函数调⽤时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占⽤内存的.
5. 函数的调⽤是需要付出⼀定的空间开销的,因为系统在调⽤函数时,要保留现场,然后转⼊被调⽤函数去执⾏,调⽤完,再返回主调函数,此时再恢复现场
内联函数:
婚外恋小说所谓"内联函数"就是将很简单的函数"内嵌"到调⽤他的程序代码中,只样做的⽬的是为了避免上⾯说到的第5点,⽬的旨在节约下原本函数调⽤时的空间开销.但必须注意的是:作为内联函数,函数体必须⼗分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。事实上,即便你没有指定函数为内联函数,有的编译系统也会⾃动将很简单的函数作为内联函数处理;⽽对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。
函数和宏函数的区别:
宏函数占⽤了⼤量的空间,⽽函数占⽤了时间。⼤家要知道的是,函数调⽤是要使⽤系统的栈来保存数据的,如果编译器⾥有栈检查选项,⼀般在函数的头会嵌⼊⼀些汇编语句对当前栈进⾏检查;同时,CPU也要在函数调⽤时保存和恢复当前的现场,进⾏压栈和弹栈操作,所以,函数调⽤需要⼀些CPU时间。
宏函数仅仅作为预先写好的代码嵌⼊到当前程序,不会产⽣函数调⽤,所以仅仅是占⽤了空间 .
⼩结:
函数体量很⼩时,为了减⼩系统的开销时间,可以使⽤宏函数,⽽函数体⽐较复杂(需要递归、循环、判断、选择等...)的
情况下,使⽤函数来定义可以避免宏函数定义带来的副作⽤。
不⾜之处->望以斧正!
-----end-----

本文发布于:2023-07-31 23:47:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1125208.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   参数   偶数   替换   内联   奇数   作为   数字
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图