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 controlioctl函数的主要作用是对文件描述符发送命令来控制设备;

  EOF

  参考:

  http://c.biancheng.net/cpp/biancheng/cpp/rumen/

本文作者:方方和圆圆

本文链接:https://www.cnblogs.com/diligenceday/p/6052413.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   方方和圆圆  阅读(283)  评论(0编辑  收藏  举报

再过一百年, 我会在哪里?

💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
点击右上角即可分享
微信分享提示