C语言复习:第四章
命名空间, 降低了代码重名的几率:
运行下面代码
#include <stdio.h> //将类定义在命名空间中 namespace diy{ class Student{ public: char *name; int age; float score; public: void say(){ printf("%s的年龄是 %d,成绩是 %f\n", name, age, score); } }; } int main(){ diy::Student stu1; stu1.name = "小明"; stu1.age = 15; stu1.score = 92.5f; stu1.say(); return 0; }
C语言中没有布尔值, 需要自己去实现:
运行下面代码
#define bool int #define false 0 #define true 1
C++中是可以直接定义布尔值的:
运行下面代码
#include <stdio.h> #include <iostream> int main(){ bool flag = true; bool flagf = false; std::cout << flag << flagf << std::endl; return 0; }
wchar_t是一种多字节类型, 在计算机中的占用位置更大:
运行下面代码
#include <stdio.h> #include <iostream> #include <wchar.h> int main(){ char ch = 'A'; wchar_t wch = 'A'; char str[] = "C语言中文网"; wchar_t wstr[] = L"C语言中文网"; printf("ch=%d, wch=%d, str=%d, wstr=%d\n", sizeof(ch), sizeof(wch), sizeof(str), sizeof(wstr)); return 0; }
调用函数时需要一定的时间和空间的开销。C++提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(inline function),又称内嵌函数或内置函数。
只要在函数前面添加inline, 那么这个函数就会变为内联函数:
运行下面代码
#include <iostream> using namespace std; inline int max(int a, int b, int c) //定义max为内联函数 { if(b>a) a=b; if(c>a) a=c; return a; } int main( ) { int i=10, j=20, k=30, m; m = max(i, j, k); cout<<"max="<<m<<endl; return 0; }
在C++中,添加了默认参数, 当我们调用某函数的时候, 函数的形参可以有一个默认值:
运行下面代码
#include <iostream> using namespace std; void fun(int i=0, int j = 10 , int c = 100) { std::cout<< i << j << c << std::endl; } int main( ) { fun(0); fun(1); fun(100); return 0; }
&引用:
运行下面代码
#include<iostream> using namespace std; int & valplus(int &a); int main(){ int num1 = 10; int num2; num2 = valplus(num1); cout<<num1<<" "<<num2<<endl; return 0; } int & valplus(int &a){ a = a + 5; return a; }
多态:
多态存在的三个条件:
- 必须存在继承关系;
- 继承关系中必须有同名的虚函数,并且它们是覆盖关系(重载不行)。
- 存在基类的指针,通过该指针调用虚函数。
注意:派生类中的虚函数必须覆盖(不是重载)基类中的虚函数,才能通过基类指针访问。请看下面的代码:
运行下面代码
#include <iostream> using namespace std; class Base{ public: void a(){ cout<<"Base::a()"<<endl; } virtual void b(){ cout<<"Base::b()"<<endl; } virtual void c(){ cout<<"Base::c()"<<endl; } }; class Derived: public Base{ public: //覆盖基类普通成员函数,不构成多态 void a(){ cout<<"Derived::a()"<<endl; } //覆盖基类虚函数,构成多态 virtual void b(){ cout<<"Derived::b()"<<endl; } //重载基类虚函数,不构成多态 virtual void c(int n){ cout<<"Derived::c()"<<endl; } }; int main(){ Base *p = new Derived; p -> a(); p -> b(); //p -> c(0); //Compile Error //p -> d(); //Compile Error Derived *d = new Derived; d->b(); return 0; }
利用虚构函数,可以有效避免因为指针问题, 没有正确析构子类的问题;
运行下面代码
#include <iostream> using namespace std; //基类 class Base{ private: int *a; public: Base(); ~Base(){ cout<<"Base destructor"<<endl; } }; Base::Base(){ a = new int[100]; cout<<"Base constructor"<<endl; } //派生类 class Derived: public Base{ private: int *b; public: Derived(); ~Derived( ){ cout<<"Derived destructor"<<endl; } }; Derived::Derived(){ b = new int[100]; cout<<"Derived constructor"<<endl; } int main( ){ Base *p = new Derived; //定义了一个子类, 子类的指针为父类 delete p; //好吧,现在把这个类删除了, 实际上并没有正确析构Deriverd,此时关键字virtual就发挥作用了; return 0; }
运行下面代码
#include <iostream> using namespace std; //基类 class Base{ private: int *a; public: Base(); virtual ~Base(){ cout<<"Base destructor"<<endl; } }; Base::Base(){ a = new int[100]; cout<<"Base constructor"<<endl; } //派生类 class Derived: public Base{ private: int *b; public: Derived(); ~Derived( ){ cout<<"Derived destructor"<<endl; } }; Derived::Derived(){ b = new int[100]; cout<<"Derived constructor"<<endl; } int main( ){ Base *p = new Derived; delete p; return 0; }
又是模版关键字..:
运行下面代码
#include <iostream> using namespace std; template<typename T1, typename T2> class Point{ private: T1 x; T2 y; public: Point(T1 _x, T2 _y): x(_x), y(_y){} T1 getX(); void setX(T1 x); T2 getY(); void setY(T2 y); }; template<typename T1, typename T2> T1 Point<T1, T2>::getX() { return x; } template<typename T1, typename T2> void Point<T1, T2>::setX(T1 x) { this->x = x; } template<typename T1, typename T2> T2 Point<T1, T2>::getY() { return y; } template<typename T1, typename T2> void Point<T1, T2>::setY(T2 y) { this->y = y; } int main( ){ Point<int, int> p(1,2); std::cout<< p.getX() << p.getY() << std::endl; return 0; }
模版类不但可以为类型参数, 也可以穿普通参数, 感觉这个就非常灵活了, 这个也是给函数传参数的另外一种形式:
运行下面代码
#include <iostream> using namespace std; template<typename T, int N> class Array{ public: Array(); T & operator[]( int ); int length(){ return len; } private: int len; T *p; }; template<typename T, int N> Array<T, N>::Array(){ p = new T[N]; len = N; } template<typename T, int N> T & Array<T, N>::operator[](int i){ if(i<0 || i>=len) cout<<"Exception: Array index out of bounds!"<<endl; return p[i]; } int main(){ Array<int, 10> arr; int i, len = arr.length(); for(i=0; i<len; i++){ //为数组元素赋值 arr[i] = 2*i; } for(i=0; i<len; i++){ //遍历数组 cout<<"arr["<<i<<"] = "<<arr[i]<<endl; } return 0; }
C++增强了对于C风格字符串的支持, 可以直接定义一个字符串, 可以替代掉原始的 char xx[100]:
运行下面代码
#include <iostream> #include <string> using namespace std; int main() { string s = "c s s"; std::cout<< s << std::endl; return 0; }
以下介绍一下string实例的几个方法:
运行下面代码
#include <iostream> #include <string> using namespace std; int main() { string s = "css1234"; //字符串的循环 int len = s.length(); for(int i=0 ; i < len ; i++) { cout << s[i] << endl; } cout << s.at(0) << endl; cout << s.at(0) << endl; cout << s.at(0) << endl; cout << s.at(0) << endl; //字符串的拼接 string s1 = "567890"; cout << "字符串拼接" << s+s1 << endl; //字符串的插入 s.insert(0,s1); cout << s << endl; //删除字符串 s.erase(0,2); cout << s << endl; //提取字符串 s1 = s.substr(1,2); cout << s1 << endl; //字符串查找 int index = s.find("123", 0); cout << index << endl; return 0; }
C捕获异常和java的捕获异常差不多, 语言的异常处理都差不多:
运行下面代码
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; int main() { string str = "abcdefg"; try{ char ch1 = str.at(100); cout<<ch1<<endl; }catch(exception e){ cout<<"[1]out of bound!"<<endl; } return 0; }
捕获异常的处理:
运行下面代码
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; int main() { string str = "abcdefg"; try{ char ch1 = str.at(100); cout<<ch1<<endl; }catch(exception e){ cout<<"[1]out of bound!"<<endl; } return 0; }
可以自己抛出异常, 然后捕获:
运行下面代码
#include <iostream> using namespace std; void test() { throw 100; } int main() { string str = "c plus plus"; try{ test(); }catch( int e ){ cout << e << endl; } return 0; }
可以在函数后面定义需要捕获的异常类型:
运行下面代码
#include <iostream> using namespace std; void test() throw(exception, int){ throw 100; } int main() { string str = "c plus plus"; try{ test(); }catch( int e ){ cout << e << endl; } return 0; }
fcntl函数可以向已经打开的fd发送命令, 重新修改fd的配置;
输入输出控制ioctl是全称是input output control, ioctl函数的主要作用是对文件描述符发送命令来控制设备;
EOF
参考:
本文作者:方方和圆圆
本文链接:https://www.cnblogs.com/diligenceday/p/6052413.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步