C/C++函数,位运算基础,字符串

C/C++函数,位运算基础,字符串

好久没有更新C++的基础知识内容了,今天就更新一下,这可能 是C/C++基础部分最后的一篇博客了

小伙伴们有什么问题或者想让我写这一部分的什么内容都可以私信或者评论留言给我哦

为避免视觉疲劳,先我多年前去过的内蒙
学会程序和算法,走遍天下都不怕
在这里插入图片描述
克什克腾旗阿斯哈图石林

函数

再不写自定义函数的时候
在编程过程中,如果数百个程序员一起写一个main的话,会非常麻烦。
如果有10000个地方需要用牛顿迭代的方法求解平方根,难道你写10000次。

so,我们要写一些自定义的函数
他实现了某些功能,并完成封装

具体的语法格式我在这里不再给大家介绍,只是稍加提点一下

1.函数声明,函数定义

2.默认的参数写在声明还是定义当中呢?还是两者都可以呢?

3.参数的传递

4.递归的函数(初步)

接下来我简单的介绍一下位运算,他在很多的程序算法设计当中都有非常重要的作用(未接触过的可以跳过这一个部分)
C/C++六种位运算符

&,|,^,~,<<,>>
他们当中除了~为单目运算符,其他都是双目运算符

他们当中具体的操作我在这里也不展开来介绍,应该再逻辑电路,计算机导论,或者大学计算机基础都会有接触到

1.&
作用:清0且保持其他位不变
ex:
你要把int型的低八位全部置为0,且其他位保持不变

n&=0xffffff00//我们看到后面这个常数低八位都是0,与出来结果就是后八位0,高24位都是1

那么就可以提个问题了
int 类型变量n 的第7位(右往左,从0开始数)是否为1

//很简单吧
n&=0x80;//0x80:1000 0000

 

2.|
作用是置1,保留其他位不变
int n 低八位全部置1

n|=0xff;//11111111,高24位保留不变

 

3.^(按位异或)
作用为取反
低八位取反

n^=0xff;//1111 1111

异或运算有一个性质
a^b=c
那么就可以有
c^b=a c^a=b
(穷举法就可以证明了,穷举所有可能情况)
原理:

可用穷举法证明:

 异或运算:1 ^ 1 = 0;1 ^ 0 = 1;  0 ^ 1 = 1;  0 ^ 0 = 0;

 穷举:

          1 ^ 1 ^ 1 = 1;

          1 ^ 1 ^ 0 = 0;

          1 ^ 0 ^ 1 = 0;

          0 ^ 1 ^ 1 = 0;

          1 ^ 0 ^ 0 = 1;

          0 ^ 1 ^ 0 = 1;

          0 ^ 0 ^ 1 = 1;

          0 ^ 0 ^ 0 = 0;

 可知任意1或0出现两次,即可抵消。

 从而推广至多个位(bit)。

 一个数异或同一个数两次,结果还是那个数。  且异或的顺序可变。

这个性质其实就是数据最原始数据加密和解密了
a为原文,b为秘钥,c为密文

异或可以实现交换两个变量的值哦

int a=5,b=7;
a=a^b;
b=b^a;
a=a^b;  //穷举法就可以证明(四种情况)

4.~
所有位取反

5.<<,>>
左移<<
丢弃高位,后面补0
左移1位,等于乘2
需要注意的是<<比乘法操作快很多很多,所以当你乘以2^n时候,不妨考虑使用左移

右移>>
符号位一同右移,在绝大多数C++/C的编译器当中,都采用 sign extension的形式补最高位,即取决于符号位,符号位是什么就什么
>>1相当于除以2往小里取整

-25>>4;//=-2

两个int变量a和n(0<=n<=31),要求写出一个表达式,要求表达式的值与a的第n位相同
你可以停下来想一下如何操作

//应该很简单吧
(a>>n)&1;
//or
(a&(1<<n))>>n;

可惜的是如果你写出来第二种答案的话,对于这条题目而言是错误的,当n=31的时候,符号位为1,我们根据我们得sign extension原则,得出来答案就不对了

 

对于这一部分有兴趣的,可以去查阅一些资料,这里作为基础部分不做过多阐述

位运算是非常非常快的,一些很厉害的学生写出来的代码,即使他的算法是不正确的,但通过位运算的优化,大大提高运算速度,偶尔可以混过。

我的博客当中有一道比较经典用位运算解决的题目,熄灯问题

字符串

字符串处理的库函数为

<cstring>

这里我提供两个不错的参考文章:

字符串处理函数大全

字符串处理

我提醒一下在for当中

//for(int i=0;i<strlen(s);++i)不要写出这样子的语句,每次调用strlen造成浪费
//改为
int len=strlen(s);
for(int i=0;i<len;++i)

实例代码

#include <iostream>
#include <cstring> //包含字符串库函数的声明
using namespace std;
int main()
{
    char title[] = "Prison Break"; //title最后一个元素是'\0'
    char hero[100] = "Michael Scofield";
    char prisonName[100];
    char response[100];
    cout << "What's the name of the prison in " << title << endl;
    cin >> prisonName; //输入字符串
    if( strcmp( prisonName, "Fox-River") == 0 ) //字符串比较函数
    cout << "Yeah! Do you love " << hero << endl;
    else {
    //字符串拷贝函数
    strcpy( response, "It seems you haven't watched it!\n");
    cout << response;
}
    title [0] = 't';
    title [3] = 0; //等效于 title [3] = '\0';
    cout << title << endl;
    return 0;
}

#include <iostream>
#include <cstring> //要使用字符串库函数需要包含此头文件
using namespace std;
void PrintSmall( char s1[],char s2[]) //输出词典序小的字符串
{
if( strcmp( s1,s2) <= 0) //如果s1小于等于s2
    cout << s1 ;
else
    cout << s2;
}
int main() {
    char s1[30]; char s2[40]; char s3[100];
    strcpy( s1,"Hello"); // 拷贝 "Hello" 到s1 , s1 = "Hello"
    strcpy( s2,s1); // 拷贝s1到s2, s2 = "Hello"
    cout << "1) " << s2 << endl; //输出 1) Hello
    strcat( s1,",world"); // 连接 ",world"到s1尾部。s1 = "Hello,world"
    cout << "2) " << s1 << endl; //输出 2) Hello,world
    cout << "3) "; PrintSmall("abc",s2); cout << endl; //输出 3) Hello
    cout << "4) "; PrintSmall("abc","aaa"); cout << endl; //输出 4) aaa
    int n = strlen( s2 ); //求s2长度
    cout <<"5) " << n << "," << strlen("abc") << endl; //输出 5) 5,3
    strupr(s1); // 把s1变成大写,s1 = "HELLO,WORLD"
    cout <<"6) " << s1 << endl; //输出 6) HELLO,WORLD
    return 0;
}

练习一下:编写一个函数:

int Strstr(char s1[],char s2[]);
如果s2不是s1的字串,返回 -1
如果s2是s1的子串,返回其在s1中第一次出现的位置
空串是任何串的子串,且出现位置为0

int Strstr(char s1[],char s2[]) {
if( s2[0] == 0)
return 0;
for(int i = 0; s1[i]; ++i) { //枚举比较起点
int k = i,j = 0;
for( ; s2[j]; ++j,++k) {
if(s1[k] != s2[j])
break;
}
if( s2[j] == 0)
return i;
}
return -1;
}

学会程序和算法走遍天下都不怕
在这里插入图片描述
克什克腾旗贡格尔草原

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值