第二周学习
来源:互联网 发布:网上装修设计软件 编辑:程序博客网 时间:2024/05/18 02:04
2.1函数指针
2.1.1定义
类型名(*指针变量名)(parameter 1, parameter 2…)
e.g:
int(*p)(int, char)
2.1.2使用方法
函数指针名(actual parameter list)
eg1:
#include <iostream>using namespace std;void outmin(int a,int b){a<b?cout<<a<<endl:cout<<b<<endl;}//条件运算符,问号前语句为真执行冒号前问号后语句,为假则执行冒号后语句int main(){ void(*p)(int,int)=outmin; p(4,5); return 0;}
返回值:4
eg2:
//qsor函数void qsort(void* base, int a, unsigned int width, int(*p)(const void*, const void*))//void qsort(数组起始地址,数组元素个数,每个元素大小,自定义大小规则)//自定义规则:如果返回值为负整数,则第一个元素在前,如果返回值是0,则相等,如果返回值是正整数,那么第一个元素在后。
eg3:
调用qsort,使数组按照个位数从小到大排序。
#include <iostream>using namespace std;int mycompare(const void* elem1,const void* elem2){ return *(int*)elem1%10-*(int*)elem2%10;//强制转换int*,然后比较个位数大小}int main(){ int an[]={8,123,11,10,4}; qsort(an,5,sizeof(int),mycompare); for(int i=0;i<5;++i){ cout<<an[i]<<endl; } return 0;}
返回值:101112348
2.2位运算
2.2.1 按位于 &
将两操作数进行与操作,只有两者的相应二进制位皆为1时,结果为1.
eg1:
21&18
21二进制: 1010118二进制: 1001021&18二进制:10000(十进制16)
eg2:
判断一个int型变量n第七位是否为1
n & 0x80==0x80
0x80:10000000若两者相等则为1
2.2.2按位或 |
将两操作数进行或操作,只有两者的相应二进制位只要有一个为1时,结果为1.
eg:
21|18
21二进制: 1010118二进制: 1001021&18二进制:10111(十进制23)
2.2.3按位异或 ^
将两操作数进行异或操作,只有两者的相应二进制位不相同时,结果为1.
eg:
21^18
21二进制: 1010118二进制: 1001021&18二进制:00111(十进制7)
ps:
1.异或运算的特点”若a^b=c,则有c^b=a, c^a=b”可以用来最简单的解密加密。
2.可以实现不通过零时变量进行两个变量值的交换:
int a=5,b=7;a=a^b;b=b^a;a=a^b;
2.2.4按位非 ~
将一操作数进行非操作,0变成1,1变成0
eg:
~21
21二进制: 0000 0000 0000 0000 0000 0000 0001 0101~21二进制: 1111 1111 1111 1111 1111 1111 1110 1010(0xffffffea)
2.2.5左移运算符 <<
a<
eg:
9<<4
9二进制: 0000 0000 0000 0000 0000 0000 0000 10019<<4二进制:0000 0000 0000 0000 0000 0000 1001 0000(十进制144)
2.2.6右移运算符 >>
a>>b
将a二进制位右移b位,移出右边丢弃。若为有符号数,右移时符号位一起移动,左边补充原符号位相同的数作为新符号位。
右移n位相当于左操作数除以
eg:
15>>2
15二进制: 1000 0000 0000 0000 0000 0000 0000 111115>>2二进制:1111 0000 0000 0000 0000 0000 0000 0011(3)
2.2.7思考题
Q:有两个int型变量a和n(
A1:
(a>>n)&1
A2:
(a&(1<<n)>>n)
2.3引用
2.3.1定义
引用等价于这个变量,对其修改等于对原变量修改
类型名&引用名=某变量名
e.g:
int n=4;int& r=n //r的类型是int&r=5;//此时n也变为5
2.3.2用法
eg1:用引用交换两个变量的值
#include <iostream>using namespace std;void swap(int &a,int &b){ int tmp; tmp=a;a=b;b=tmp;}int main(){ int n1=5,n2=3; swap(n1,n2); cout<<n1<<" "<<n2<<endl; return 0;}
3 5
eg2:引用作为返回值
#include <iostream>using namespace std;int n=4;int& setvalue(){ return n;}int main(){ setvalue()=40; cout<<n<<endl; return 0;}
40
2.3.3常引用
常引用不能通过引用的量来修改原来的值。
int n;const int& r=n;
2.4const关键字和常量
2.4.1定义常量
const int max=23const double pi=3.14const char* p="hello world!"
2.4.2定义常量指针
不可通过常量指针修改其指向的内容
int n,m;const int* p=&n;*p=5//编译出错,不可通过常量指针修改指定内容n=4;//okp=&m;//ok,但常量指针的指向可以变化
不能把常量指针赋值给非常量指针,但反过来可以
const int* p1; int* p2;p1=p2;//okp2=p1;//编译出错,不可将非常量赋值给常量p2=(int*)p1;//ok,强制类型转换,但有风险
函数参数为常量指针时,可避免函数内部不小心改变参数指针所指向的地方(后面函数的参数一般都如此定义)
void myprint(const char* p){strcpy(p,"this");//编译出错,不可改变参数指针指向的地方cout<<*p<<endl;//ok,简单的调用可以,但不能改变}
2.5动态内存分配
2.5.1用new运算符实现动态内存分配
2.5.1.1第一种用法,分配一个变量
t* p=new t;//p为t*类指针
2.5.1.2第二种用法,分配一个数组
t* p=new t[n];//p为t*类指针,n为数组个数
ps:特别注意的是,p作为数组时,可以用p[n]调用数组中第n个元素,很常见
2.5.2用delete运算符释放动态分配的内存
用new分配的内存空间,一定要记得用delete进行释放
2.5.2.1删除 new出来的变量
int* p=new int;*p=5;delete p;delete p;//编译错误,空间不能被delete多次
2.5.2.2删除new出来的数组
int* p=new int[20];p[0]=1;delete [] p;
2.6内联函数
减少函数调用的开销
用法如下:
inline int max(int a, int b){return a<b?b:a;}
2.7函数重载
多个函数有同一个函数的名字,但函数的参数类型不同,叫做函数的重载
ex:以下三个是重载关系
int max(double n1, double n2){}int max(int n1, int n2){}int max(int n1, int n2, int n3){}
编译器会根据实际传入的参数来判定调用哪个函数。
ex:
max(3.2,2.5);//调用上述第一行的函数max(2,4);//调用上述第二行的函数max(1,2,3);//调用上述第三行的函数
2.8函数的缺省函数
调用函数时,可以不写相应的参数,编译器会以缺省值代替
void func(int x1, int x2=2, int x3=3){cout<<x1+x2+x3<<endl;}func(10);//等效于func(10,2,3)func(10,8);//等效于func(10,8,3)func(10, ,8);//编译错误,只能最右边的连续若干个参数缺省
可以提高程序的可扩充性
2.9类的基础定义
2.9.1类的定义
class 类名{访问说明符: 变量1 变量2 成员函数访问说明符: 变量3 变量4 成员函数};
2.9.2调用类中的成员变量和成员函数
用法1:
对象名.成员函数名字/成员变量名字
用法2:
对象指针->成员函数名字/成员变量名字
用法3:
引用名.成员名
eg:
#include <iostream>using namespace std;class crectangle{public: int w,h;//成员变量 void init(int a,int b){w=a;h=b;}//成员函数1 int area(){return w*h;}//成员函数2 int perimeter(){return 2*(w+h);}//成员函数3};int main(){ int w=4,h=6;//第一种调用 crectangle r;//从类中建立一个新的对象r,这个r拥有上述类所有的成员变量和成员函数 r.init(w,h);//调用成员函数初始化成员变量 cout<<r.area()<<endl<<r.perimeter()<<endl;//第二种调用 crectangle* p=&r;//对象指针p p->init(w,h);//第二种调用方式 cout<<p->area()<<endl<<p->perimeter()<<endl;//第三种调用 crectangle& rr=r; rr.init(w,h); cout<<rr.area()<<endl<<rr.perimeter()<<endl; return 0;}
242024202420
也可以只在定义类的时候只申明函数,在外面写函数体
class rectangle{public: int w,h; int area(); int perimeter(); void init(int a, int b)};void rectangle::init(int a,int b){w=a;h=b;}//成员函数1int rectangle::area(){return w*h;}//成员函数2int rectangle::perimeter(){return 2*(w+h);}//成员函数3
2.10类成员的可访问范围
在上一节定义类的时候,有个访问说明符,分类如下:
private:其成员只能被成员函数访问
public:可以在任何地方访问
protected:后面会提到,有关于基类/派生类
#include <iostream>using namespace std;class crectangle{public: int w,h; void init(int a,int b){w=a;h=b;} int area(){return w*h;} void seta(int x){a=x};private: int a; int perimeter(){return 2*(w+h);}};int main(){ int w=4,h=6; crectangle r; r.init(w,h);//ok,可以调用public成员 cout<<r.area()<<endl//ok,可以调用publlic成员 cout<<r.perimeter()<<endl;//编译错误,不能调用private成员 r.w=5;//ok,可以调用 r.a=6;//编译错误,不能调用private成员 r.seta(6);//ok,想修改private的值只能通过其public成员函数 return 0;}
- 第二周oracle学习
- 暑假学习第二周
- 第二周学习Python
- 机器学习 第二周
- Linux 学习第二周
- 第二周学习小结
- 学习java第二周
- 学习python第二周
- Unity学习第二周
- 第二周学习
- 第二周学习
- 暑假学习第二周
- 第二周学习收获
- 第二周学习总结
- 第二周学习内容
- 机器学习第二周
- 第二周学习笔记
- linux 学习第二周小结
- 排序算法 -- (五)冒泡排序
- linux中fork()函数
- 环信聊天
- git远程仓库和本地仓库的使用
- tensorflow——调试Image_retrain出现问题二
- 第二周学习
- jdk 历史版本下载地址
- 用PowerDesigner15自动将数据库里的表生成ER图
- 走过最长的路是你的套路(PS调色-V客学院技术分享)
- linux下php调用unoconv命令将doc,ppt转pdf,pdf在转图片
- Linux CRC校验
- Vue中保存用户登录状态
- Laravel 5.4 官方文档摘记:视图
- Windows下安装DB2-Express-C并创建schema测试连接