新闻资讯网站备案,济南网络营销外包,免费制作婚介网站,南京模板建站定制网站目录 上期答案揭晓#xff1a;
回忆#xff1a;
问题1展现#xff1a;
问题2展现#xff1a;
改进方案#xff1a;
下期预告#xff1a;C语言类型转换的问题。 上期答案揭晓#xff1a;
上期的问题大家是否都有了想法#xff0c;下面说说我的思路。
上次我们提到…目录 上期答案揭晓
回忆
问题1展现
问题2展现
改进方案
下期预告C语言类型转换的问题。 上期答案揭晓
上期的问题大家是否都有了想法下面说说我的思路。
上次我们提到如果是字符数组做函数的参数那么函数将会发生什么变化。那个问题的关键就是求数组的长度因为数组在函数参数中会退化成为指针导致数组长度变化从而发生错误转化一下就是字符数组如何求长度的问题。还记得我们这个系列的第一节我们提到过的字符数组的结尾会有\0作为终止符所以我们只需要做一个循环就可以算出字符数组的长度然后将长度作为函数参数带入函数就可以完成。 请看代码
#include iostream
using namespace std;
size_t getStringLength(const char* str)
{size_t length 0;while (str[length] ! \0)
{length;}return length;
}int main()
{const char* myString Hello, World!;std::cout The length of the string is: getStringLength(myString) std::endl;return 0;
}因为数组退化成指针所以函数参数那里直接写指针也是没有问题的。
C语言数组退化问题和改进 这篇文章我们来看一下移位运算的问题。不知道大家是否还记得我们之前了解过的位运算符。位运算符就是与位相关的运算符下面就让我们看一看今天的问题吧。C运算符表达式和基本语句——逻辑运算符和位运算符 回忆 位运算符包括按位或按位与按位异或按位取反左移右移运算符。 今天的问题实际上我们在说位运算符的那一章就出现过端倪接下来就让我们看一看问题所在。 问题1展现
逻辑右移还是算术右移左移是相同的
这个问题我们之前讨论过关于是那种方式与编译器有关但是我们还是要看看具体的表现然后避免这种模棱两可的方式使我们的代码可以跨平台运行。
#include iostream
using namespace std;
int main()
{
char a10x63;//0110 0011
a1(a14);
printf(0x%x\n,a1);//0011 0000char a10x63;//0110 0011
a1(a14);
printf(0x%x\n,a1);//0000 0110逻辑右移char a20x95;//1001 0101
a1(a24);
printf(0x%x\n,a2);//0101 0000char a20x95;//1001 0101
a1(a24);
printf(0x%x\n,a2);//1111 1001算术右移return 0;
}
我们可以看到左移的时候不会发生特殊情况但当我们右移的时候就会出现两种情况就会出现特殊情况。逻辑右移是因为0110 0011右移四位后0110是会保留下来的且开头是0所以补位的也是0。算术右移是因为1001 0101右移四位后1001保留下来但是开头是1所以补位也是1。
那么如何避免这种模棱两可的方法呢官方给出的答案是将有符号的数变成无符号的数那么所有的右移就会变成逻辑右移补零的方案从而达到可移植性。
#include iostream
using namespace std;
int main()
{
char a10x63;//0110 0011
a1(a14);
printf(0x%x\n,a1);//0011 0000char a10x63;//0110 0011
a1(a14);
printf(0x%x\n,a1);//0000 0110逻辑右移unsigned char a30x95;//1001 0101
a1(a34);
printf(0x%x\n,a3);//0101 0000unsigned char a30x95;//1001 0101
a1(a34);
printf(0x%x\n,a3);//0000 1001 逻辑右移return 0;
}
只需要加上unsigned就可以将有符号的数改成无符号的数那么就可以统一成为逻辑右移补0。 问题2展现
移位操作位数的限制
#include iostream
using namespace std;
int main()
{
const unsigned char priv0xff;
const unsigned char P_BACKUP(17);
const unsigned char P_ADMIN(18);
if(priv P_BACKUP)
{
coutBACKUPendl;
}
if(priv P_ADMIN)
{
coutADMINendl;
}
return 0;
}
我们预测一下上面的结果会输出什么。答案是BACKUP。这个问题十分的明显那就是我们在移位的过程中导致移位超过了char型变量的长度8位从而引发错误。所以我们在开始移位的时候就会发现错误我们应该这样改 const unsigned char P_BACKUP(16); const unsigned char P_ADMIN(17);这样结果就会显示BACKUPADMIN两个答案。 改进方案
其实这类的改进我们只需要记住char型的长度是8int型一般为32记清楚每个类型的变量存储的大小那么就不会出现上述的错误。如果移位超过了存储长度那么其实就相当于删除因为超出长度的那部分没有意义。
当然C也是给出了改进方案比如我们不知道这个类型的存储长度那么我们就用bitset的方法来定义一个长度比如我们忘记了char是八个字符那么我们就自定义一个长度比如说10那么我们就不会导致移位过程中超出存储长度而发生错误。
#include iostream
#include bitset
using namespace std;
int main()
{
bitset10 priv0xff;
bitset10 P_BACKUP(16);
bitset10 P_ADMIN(17);
if(priv P_BACKUP)
{
coutBACKUPendl;
}
if(priv P_ADMIN)
{
coutADMINendl;
}
return 0;
}
看代码中的自定义长度就可以避免我们的移位超出存储长度这就是C的解决方案也是很简单的但是我认为还是要记清楚各个类型的存储长度。
到这里这篇关于C语言移位运算的陷阱就说完了求一个免费的赞感谢阅读。
下期预告C语言类型转换的问题。