风筝的C++随时记

关于常量指针和指针常量

两个概念经常混淆啊,这是在考中文四六级啊,所以我给这两个概念起个长一点的名字。

常量指针 = 指向常量的指针

指针常量 = 指针是一个常量

前者的意思是,一个指针,它指向的地址所存放的数据是一个常量,这个地址里存的数据是不可变的,而这个指针是可以改变的,可以改变这个指针所指向的地址。

其定义形式为:int const *p = &m; 还有一种定义形式:const int *p = &m;

后者的意思是,一个指针,它本身就是一个不可变的常量,也就是说这个指针指向的地址是不可变的,而这个地址里所存放的数据是可以改变的。

其定义形式为:int* const p= &m;

找到一种帮助记忆的方法:无论哪种定义形式,我们规定带*号的就说成指针,所以观察定义的形式,有下划线的表示为常量,不带下划线的表示为指针,则从左向右读就是正确的含义。

关于按位运算符

下表列出了按位运算符。

运 算 符

说 明

~

这是按位求反运算符。它是一个一元运算符,可以反转操作数中的位,即1变成0,0变成1

&

这是按位与运算符,它对操作数中相应的位进行与运算。如果相应的位都是1,结果位就是1,否则就是0

^

这是按位异或运算符,它对操作数中相应的位进行异或运算。如果相应的位各不相同,例如一个位是1,另一个位是0,结果位就是1。如果相应的位相同,结果位就是0

|

这是按位或运算符,它对操作数中相应的位进行或运算。如果两个对应的位中有一个是1,结果位就是1。如果两个位都是0,结果就是0

表中的运算符按照其优先级排列,在这个集合中,按位求反运算符的优先级最高,按位或运算符的优先级最低。在附录D的运算符优先级表中,按位移动运算符<<和>>具有相同的优先级,它们位于~运算符的下面,&运算符的上面。(摘自这篇文章)。

具体用法可以参考其他文章,这里只从一个进制转换的例子简单分析其中两个运算符的用法。下面给出十进制数转换为二进制并输出。

void tenTOtwo()
{
    cout<<"输入一个10进制数:"<<endl;
    int x;
    cin>>x;
    int len = sizeof(int)*8;  //sizeof(int)的值为4 即一个int型占4个字节,每个字节8bit,一个int型就占了32bit
    for (int i = len-1;i>-1;i--) //循环32次
    {
        /*int temp = 1<<i;
        int s = 1<<i;
        char* temp1 = x&1<<i?"1":"0";
        cout<<"5&"<<s<<"="<<temp1<<endl;*/
        char* temp = x&1<<i?"1":"0";  //x和1左移i位后的数求与运算
        cout<<temp;
        if(i%8==0) //每到8个bit(即一个字节) 输入一个空格
            cout<<" ";
    }
    
    cout<<endl;
}

这个算法非常巧妙的利用了"按位与操作"和"按位左移操作"。首先说明一下这两个操作符的效果。

按位与运算:两个位做与运算,全都为1,则结果为1,否则为0;

例如二进制2(00000010)与二进制3(00000011)

00000010

&

00000011

00000010 结果是2。

左移运算:n<<m;将n左移m位,相当于将n的二进制位整体向左移动m位,左侧移除的舍弃,右侧移进的补0。效果就是把每一个位乘以2的m次方,也就是n*2m。

例如int val = 8<<3; 将2(00001000)向左移动3位,变为64(01000000),即8*23= 8*8=64。

分析一下这个算法的大体思路:

1.确定一个int型变量所占的位数,32位int占用4个字节,每个字节占用8个bit,所以一个int型变量占用32个bit。

2.循环32次,每次只设定其中一个bit为1,令只有一个bit为1的32位二进制与待转换的十进制数按位与运算。

3.按位与运算,结果为1,则这个32位二进制中当前为1的位所对应的这个十进制数的位也为1。

然后看具体代码:

int len = sizeof(int)*8;   //获取一个int型整数占多少个bit

然后 for (int i = len-1;i>-1;i--) 循环32次,每次将1(00000000 00000000 00000000 00000001)向左移i位。第1次移动31位,即:10000000 00000000 00000000 00000000第2次移动30位,即:01000000 00000000 00000000 00000000

第3次移动29位,即:00100000 00000000 00000000 00000000.....

第30次移动2位,即:00000000 00000000 00000000 00000100

第31次移动1位,即:00000000 00000000 00000000 00000010

第32次移动0位,即:00000000 00000000 00000000 00000001用移位后的二进制数2的31次方、2的30次方....直到2的1次方、2的0次方和待转换的数字x进行与(&)运算。

假如x&2的31次方,结果为1,则x的第一位是1,否则就是0。以此类推,便可通过32次的循环,得到哪些位是1,哪些位是0。

这里输入十进制的5,将5转换为二进制。程序运行结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Bingo的深度学习杂货店

Q78 Subsets

Given a set of distinct integers, nums, return all possible subsets (the power s...

3058
来自专栏柠檬先生

Python 基础 高阶函数

python 把函数作为参数   如果传入abs 作为参数     def add(x,y,y):       return f(x) + f(y)     a...

3089
来自专栏武培轩的专栏

Leetcode#344. Reverse String(反转字符串)

852
来自专栏一“技”之长

Swift解读专题三——基础运算符 原

        运算符是编程语言不可缺少的一个部分,Swift中除了支持C中的运算符外,还提供了一些更加强大的运算符功能,例如取余符%可以用来计算浮点数,另外新...

502
来自专栏Java帮帮-微信公众号-技术文章全总结

14(01)正则表达式,Pattern,Mactcher,Math,BigInteger,BigDeximal,System等

学正则表达式之前qq号问题: package cn.itcast_01; import java.util.Scanner; /* * 校验qq号码. * ...

2885
来自专栏赵俊的Java专栏

合并排序数组

2951
来自专栏calmound

Javascript字符串

## 定义 ``` var str = new String("abcdefg"); var str = "abcdefg"; ``` ## 常用方法 ###...

2946
来自专栏Java与Android技术栈

Scala学习笔记(八)

模式匹配是 Scala 的重要特性之一,前面两篇笔记Scala学习笔记(六) Scala的偏函数和偏应用函数、Scala学习笔记(七) Sealed Class...

1643
来自专栏积累沉淀

Python快速学习第六天

第六天: 面向对象 1. 面向对象的特点——多态,封装,继承  对象:包括特性和方法,特性只是作为对象的一部分变量,而方法则是存储在对象内的函数。 (1)多态—...

1927
来自专栏androidBlog

表达式(四则运算)计算的算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

3261

扫码关注云+社区

领取腾讯云代金券