C++学习(二)

编译器编译过程 :

        编译{

            预编译: 注释删除、宏替换、头文件包含、条件编译等

            编译:   语法检查、符号汇总

            汇编:   符号表生成 (存有符号的名称和其存储在内存中的地址) (若某个符号仅声明未定义则符号表中就会存储一份虚拟地址)

        }

        链接{

            合并段表

            符号表的合并及重定位

        }

    C++基础:

{

        #include <iostream>      // 包含iostream头文件

        iostream 库              // 包含两个基础类型: 输入流istream 输出流ostream

        'cin' : {

            标准输入流  用于从控制台读取输入数据

            输入运算符 '>>'  默认情况下跳过空白符 读入后面与变量类型对应的值(给一组变量赋值时可用空格符 回车符 制表符将输入数据间隔开)

                            输入字符串时 跳过空白符 读入非空白字符 直到另一个空白字符为止 并在串尾放置字符串结束标志 '\0'

            eg:{

                int cinX ;

                cin >> cinX ;   // 读取变量x

            }

        }

        'cout' : {

            标准输出流  用于向控制台输出数据

            输出运算符 '<<'

            eg:{

                cout << "Hello, world!" ;         // 输出字符串 "Hello, world!"

            }

        }

        标准错误

            cerr  用于输出错误信息

        运行时信息

            clog  用于输出运行时信息

        'endl' : 刷新缓冲区 即换行


 

        '::' : {

            作用域标识符: 用于区分同名的变量和函数 作用域指的是变量或函数的可访问范围 全局作用域 局部作用域 命名空间作用域

               当全局变量与函数中某个局部变量重名 则可通过'::'来区分

               eg:{

                   int zozoX;  //全局变量

                   int anyfunc() {

                        int zozoX;  //局部变量

                        ::zozoX = ::zozoX * zozoX;  // 其中 '::zozoX' 指代全局变量  'zozoX'指代局部变量

                        return ::zozoX;

                   }

               }

               可通过 '命名空间名称 :: 命名空间成员' 的方式访问命名空间成员

               eg:{

                   std::cout << "Hello, world!" ;         // 输出字符串 "Hello, world!"

                   注释: std 命名空间  cout是该命名空间的成员  std::cout 访问该命名空间的cout成员

               }

               假设 A、B 表示两个类 在A、B中都有成员member

               那么可以通过 A::member 和 B::member 访问各自的member

               假设声明了一个类Zozo ,声明了一个成员函数zozoFunc(), 在类中未给出定义 则类外定义时使用 '类名::成员函数名(形参表)'

               eg:{

                    class Zozo {

                        public:

                            int zozoFunc();

                            ...

                    };

                    int Zozo::zozoFunc()         //  类名::成员函数名(形参表)

                    {

                        ...

                    }

               }

        }


 

        'const' 常量限定符:{   修饰常量  const对象必须初始化

               const float PI = 3.14 ; // 此时PI是个常量 不能修改 类似于宏定义 #define PI 3.14

               float const PI = 3.14 ; // 与上例等价

               /* 若想在多个文件之间共享const对象 则需要在定义变量之前加上 extern */

               extern const int buffer = 695;   //定义

               extern const int buffer;         // 外部调用形式

               指向常量的指针:一个指向常量的指针变量  '非const指针 const数据'

               {

                    const char* ptr = "abcd";   //指针变量ptr指向一个常量字符串 'abcd'   const位于*右侧

                    ptr[3] = 'x' ;             // error: 不能修改常量字符串的内容

                    ptr = "efgh";              // 指针是变量 可以改变ptr所指的地址

               }

               常指针:将指针变量所指的地址声明为常量  'const指针 非const数据'

               {

                    char* const ptr1 = "myName";  //指针常量ptr1指向一个字符串 "myName"  const位于*右侧

                    ptr[3] = 'L' ;                // 可以修改ptr1所指的地址的内容

                    ptr = "world!" ;              // error: 不能修改指针ptr1指向的地址

               }

               指向常量的常指针:指针指向的地址及地址中的内容均不可改变 'const指针 const数据'

               {

                    const char* const ptr2 = "you are my hart";         // 指针常量ptr2指向常量字符串  const位于*两边

               }

               总结: '左定值 右定向 const修饰不变量'

               常量一旦建立 任何地方都不能修改

        }

/* ----------- practice 1.0 -----------*/

#include <iostream>  // for input/output operations

int main()
{
    int zozoX , zozoY;
    int zozoSum = 0;

    std::cout << "please enter the value of zozoX and zozoY: " << std::endl;
    std::cin >> zozoX >> zozoY ;
    std ::cout << std::endl;
    zozoSum = zozoX + zozoY;
    std::cout << "The sum of zozoX and zozoY is: " << zozoSum << std::endl;

    int zozoR = 15;
    const float zozoPI = 3.14;
    // zozoPI = 3.14159;       // error: assignment of read-only variable 'zozoPI'
    float zozoArea = zozoPI * zozoR * zozoR;
    std::cout << "The area of zozoCircle is: " << zozoArea << std::endl;

    char zozoStr[5] = "zozo";
    const char *zozoName = zozoStr;     // 指向常量字符串的指针变量
    // zozoName[3] = 'L';       // error: assignment of read-only location 'zozo'
    zozoName = "Tom";
    std::cout << "The myname is: " << zozoName << std::endl;
    std::cout << "The address of myname is: " << &zozoName << std::endl;
    std::cout << "The address of zozoStr is: " << &zozoStr << std::endl;

    int* const zozoNewPtr = &zozoR; // 指向变量的指针常量
    *zozoNewPtr = 100;
    // zozoNewPtr = &zozoSum;  // error: assignment of read-only variable 'zozoNewPtr'
    std::cout << "The value of zozoR is: " << *zozoNewPtr << std::endl;
    std::cout << "The address of zozoR is: " << zozoNewPtr << std::endl;

    const int *const zozoPtr = &zozoSum; // 指向常量的常指针
    // *zozoPtr = 100;       // error: assignment of read-only variable 'zozoPtr'
    // zozoPtr = &zozoX;  // error: assignment of read-only variable 'zozoPtr'
    std::cout << "The value of zozoSum is: " << *zozoPtr << std::endl;
    std::cout << "The address of zozoSum is: " << zozoPtr << std::endl;


    return 0;
}

        'void' :{

                通常表示无值 将void作为指针类型时 表示不确定类型 void型指针是一种通用型指针 任何类型的指针值都可以赋给void类型

                已获值的void型指针 处理时 须进行显示类型转换

                void *pc;

                int i = 123;

                char str = 'a';

                pc = &i;

                cout << pc << endl;          // 输出指针的地址

                cout << *(int*)pc << endl;   // 输出值123

                pc = &str;

                cout << *(char*)pc << endl;  // 输出值a

        }

        'inline' :{

                函数名前冠以 inline 关键字 表明该函数是内联函数 编译器将在调用该函数的地方将其展开 使得程序运行速度更快

                inline int zozoAdd(int zoa, int zob) {

                    return zoa + zob;

                }

                int main() {

                    int zozoRes = zozoAdd(10, 20);

                    return 0;

                }

                注释 :内联函数以空间换时间 内联函数体内一般不含复杂语句 如for、switch等

                      内联函数不宜冗长且频繁调用  inline函数的定义最好放在头文件中

        }


 

    带有默认参数的函数:{

            进行函数调用时 编译器从左至右依次将实参与形参结合 若未指定足够实参 则使用默认值

            void init(int x = 10, int y = 9);

            init(100, 20);       //100 , 20

            init(40);           //40 , 9

            init();             //10 , 9

            注释: 带默认值的参数必须从从右至左依次出现

            void init(int x, int y, int z = 100);

            void init(int x, int y = 30, int z = 100);

            void init(int x, int y = 30, int z);   // error!!!!!!!!!!!

            如果函数声明和函数定义分开写 函数声明和函数定义不能同时设置默认参数 建议函数声明时设置参数

            eg:{

                int zozoFunc(int x = 10, int y = 20);

                int main()

                {

                    cout << zozoFunc() << endl;

                    return 0;

                }

                int zozoFunc(int x, int y)

                {

                    return x + y;

                }

            }

    }

/* ---------------------- pratice 1.1 --------------------------- */

#include <iostream>  // for input/output operations

using namespace std;   // 声明命名空间

inline int add(int a, int b);  //内联函数

int main()
{
    int zozoI = 10;
    char zozoC = 'a';
    void *zozoPtr = nullptr;    // void型指针 即通用指针
    zozoPtr = &zozoI;           // 已获值指针
    cout << "The value of zozoI is: " << *(int*)zozoPtr << endl;  // 进行显示类型转换
    zozoPtr = &zozoC;
    cout << "The value of zozoC is: " << *(char*)zozoPtr << endl; // 进行显示类型转换
    cout << "The address of zozoPtr is: " << zozoPtr << endl;
    cout << "The address of zozoC is: " << &zozoC << endl;


    char zozoBuf[10] ="hello";
    char *zozoBufPtr = zozoBuf;

    cout << "address of zozoBuf: " << &zozoBuf << endl;        // 输出 0x7ffffb542a1e 地址
    cout << "address of zozoBuf: " << (int*)zozoBuf << endl;    // 输出 0x7ffffb542a1e 地址
    cout << "zozoBuf: " << zozoBuf << endl;           // 输出 hello 即数组buffer的内容

    cout << "zozoPtr: " << zozoBufPtr << endl;      // 输出 hello 即数组buffer的内容
    cout << "address of zozoPtr: " << (int*)zozoBufPtr << endl;  // 输出 0x7ffffb542a1e 地址 即zozoBuf的地址
    cout << "address of zozoPtr: " << &zozoBufPtr << endl;        // 输出zozoBufPtr本身的地址 即指针的地址 与数组地址不同


    int zozoX,  zozoY;
    cout << "Enter two numbers for zozoX and zozoY: " << endl;
    cin >> zozoX ;
    cin >> zozoY ;
    int zozoSum = add(zozoX, zozoY);  // 调用内联函数
    cout << "The zozoSum is: " << zozoSum << endl;


    double IntX = 10.99;
    int DoubleY = (int)IntX;
    cout << "The value of DoubleY is: " << DoubleY << endl;

    return 0;
}

inline int add(int a, int b)
{
    return a + b;
}

    函数重载:{

            同一作用域 函数参数列表(类型or个数or顺序)一个及以上不同 但函数名称相同 称为函数重载

            int add(int a, int b)

            {

                return a+b;

            }

            double add(double a, double b)

            {

                return a+b;

            }

            int add(int a, int b, int c)

            {

                return a+b+c;

            }

            int main() {

                int a=6, b=9, c=5;

                double d=3.14, e=2.71;

                cout << add(a,b) << endl;    // 输出 15

                cout << add(d,e) << endl;    // 输出 5.85

                cout << add(a,b,c) << endl;  // 输出 20

                return 0;

            }

            注释: 只有返回值类型不同的函数 不允许重载

                 若函数重载与带默认值函数同时使用 可能引起二义性

                 若给出实参和形参类型不相符 可能产生不可识别错误

    }

    强制类型转换:{

           int x = 10;

           double y = double(x);  // 强制类型转换 整数转浮点数  或者  double y = (double)x;

    }

    'new' 和 'delete' :{

        同c语言中的 malloc 和 free 函数  分配和释放堆区内存

        格式 : 指针变量名 = new 类型;

               delete 指针变量名;

                eg:{

                    int *p ;

                    p = new int ;

                    delete p ;

                }

        注释:

            new分配的空间 结束后用delete释放 否则该部分空间变为不可回收的死空间

            使用new分配内存时 不能满足分配要求 则new返回空指针NULL

            new 可为数组动态分配内存及释放 形式如下:

                指针变量名 = new 类型 [下标表达式];

                delete [] 指针变量名;

                eg:{

                    int *p = new int[10];

                    delete [] p;

                }

            new 可在为简单变量分配空间时进行初始化 形式如下:

                指针变量名 = new 类型(初值);

                eg:{

                    int *p;

                    p = new int(99);  // p指向一个值为99的int型变量

                    delete p;

                }

    }

/* ----------- practice 1.2 -----------*/

#include <iostream>  // for input/output operations

using namespace std;

int main()
{
    int *p;

    p = new int;    // 为指针分配内存
    cout << "The 1st value of p is: " << *p << endl;
    delete p;

    p = new int(695);    // 为指针分配内存 并设置初值
    cout << "The 2nd value of p is: " << *p << endl;
    delete p;

    p = new int[5];    // 为指针数组分配内存 该数组有5个元素
    p[2] = 69;
    cout << "The value of p[2] is: " << p[2] << endl;
    delete[] p;

    int x = 42;
    int &r = x;    // 引用变量
    cout << "The value of x is: " << x << endl;
    cout << "the value of r is :" << r << endl;
    cout << "The address of x is: " << &x << endl;
    cout << "the address or r is: " << &r << endl;

    return 0;
}

    引用:{

            变量的引用就是变量的别名 故引用又称别名

            引用与其代表的变量共享一内存单元 系统不为引用另外分配存储空间 引用及其代表的变量具有相同地址

            格式:类型 &引用名 = 已定义变量名;        //(类型& 引用名 = 已定义变量名 or 类型 & 引用名 = 已定义变量名)

                  eg:{

                    int x = 10;

                    int &j = x;  // int& j = x;  int & j = x;

                    cout << "j = " << j << endl;

                    cout << "i的地址为 " << &i << endl;

                    cout << "j的地址为 " << &j << endl;

                  }

            注释: 引用非独立数据类型 必须与某一变量联系 且声明时需立即初始化

                  指针通过地址间接访问变量 引用通过别名直接访问变量

                  引用可以被用作函数参数 也可以被用作函数的返回值

                  eg:{

                    void swap(int &a, int &b)          // 引用作为函数参数

                    {

                        int temp = a;

                        a = b;

                        b = temp;

                    }

                    int a[] = {3, 4, 5, 6, 7};

                    int& get_datastr(int i)     // 引用作为函数返回值

                    {

                        return a[i];

                    }

                  }

            不允许建立void类型引用 不能建立引用的数组 不能建立引用的引用 不能建立指向引用的指针

            可以将引用的地址赋值给一个指针 此时指针指向原变量

            可以用const修饰引用 此时不允许通过引用改变变量的值 但不阻止原变量的值被改变

    }

/* ----------- practice 1.3 -----------*/

#include <iostream>  // for input/output operations

using namespace std;

void swap(int &a, int &b)  // 引用作为函数参数
{
    int temp = a;
    a = b;
    b = temp;
}

int a[] = {3, 4, 5, 6, 7};

int& get_datastr(int i)     // 引用作为函数返回值
{
    return a[i];
}

int main()
{
    int a1 = 12 , b1 = 11;
    swap(a1, b1);
    cout << "a1 = " << a1 << "b1 = " << b1 << endl;

    int testIndex = 2;
    cout << "The value of a[" << testIndex << "] is: " << get_datastr(testIndex) << endl;
    get_datastr(testIndex) = 100;
    cout << "changed The value of a[" << testIndex << "] is: " << get_datastr(testIndex) << endl;

    int num = 10;
    int &renum = num;
    int *pointer ;
    pointer = &renum;
    cout << "The value of num is: " << num << endl;
    cout << "The value of renum is: " << renum << endl;
    cout << "the address of num is: " << &num << endl;
    cout << "the address of renum is: " << &renum << endl;
    cout << "the address of pointer is: " << pointer << endl;

    const int& renum2 = num;
    cout << "The value of renum2 is: " << renum2 << endl;
    // renum2 = 20;        // error: assignment of read-only variable 'renum2'
    num = 30;
    cout << "The value of num is: " << num << endl;
    cout << "The value of renum2 is: " << renum2 << endl;


    return 0;
}

  }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值