C++简介


一、基本的输入/输出

   1、cin和cout分别istream类和ostream类 的对象,用来实现基本的键盘输入和屏幕输出。

   2、在C++类库提供的头文件中已经对“>>”和“<<进行了重载,使之分别作为流提 取运算符和流插入运算符,在C++中,可以使用流提取运算符“>>”从标准输入设备键盘取得数据,使用流插入运算符“<<”从输出数据。

  3、用户自定义的类型的数据,不能直接用“>>”和“<<”进行输入/输出,必须对“>>”和“<<"进行运算 符重载(std)后才可以使用。

    格式示例:

cin>>变量1>>变量2>>...变量n; cout<<表达式1<<表达式2<<...<<表达式n;

 

二、头文件和命名空间

   1、iostream是C++的标准输入输出流。当在程序中使用cin或cout时,必须在程序的最前面包含这个流。

   2、每条#include指令仅可以包含一个头文件,如果需要包含多个头文件,则需要使用多条#include指令。

   3、常用的头文件

标准输入输出流:<iostream>
标准文件流:<fstream>
标准字符串处理函数:<string>
标准数学函数:<cmath>

  4、#include <iostream>和 #include "iostream"。使用尖括号括住系统提供的头文件,使用双引号括住 用户当前目录下或指针的目录查找要包含(程序员自己定义)的头文件。

    5、C++提供了using语句,可以简化命名空间的写法。using语句有两种形式:

    using 命名空间名::标识符;    //表示可以在本文件中直接使用该标识符
    usingnamespace 命名空间名;  //表示可以在本文件中直接使用指定命名空间内的所有标识符

     using 指令也可以用来指定命名空间中的特定项目。例如,如果您只打算使用 std 命名空间中的 cout 部分,可以使用 using std::cout; 方式。随后的代码中,在使用 cout 时就可以不用加上命名空间名称作为前缀,但是 std 命名空间中的其他项目仍然需要加上命名空间名称作为前缀,如下所示:

#include <iostream>
using std::cout; int main () { cout << "std::endl is used with std!" << std::endl; return 0; }

 

     为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称(如:name::code; // code 可以是变量或函数

#include <iostream>
using namespace std; // 第一个命名空间
namespace first_space{ void func(){ cout << "Inside first_space" << endl; } } // 第二个命名空间
namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } int main () { // 调用第一个命名空间中的函数
 first_space::func(); // 调用第二个命名空间中的函数
 second_space::func(); return 0; }

 

 三、关键词

关键词 介绍
static_cast
static_cast < type-id > ( expression )

该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

  • ① 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
  • ② 用于基本数据类型之间的转换,如把 int 转换成 char,把 int 转换成 enum。这种转换的安全性也要开发人员来保证。
  • ③ 把空指针转换成目标类型的空指针。
  • ④ 把任何类型的表达式转换成void类?

注意 static_cast 不能转换掉 expression 的 const、volitale、或者 __unaligned 属性。

const

const(常量的,constant)所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。在 C++ 中,用 const 声明一个变量,意味着该变量就是一个带类型的常量,可以代替 #define,且比 #define 多一个类型信息,且它执行内链接,可放在头文件中声明;但在 C 中,其声明则必须放在源文件(即 .C 文件)中,在 C 中 const 声明一个变量,除了不能改变其值外,它仍是一具变量。如:

const double pi(3.14159);  const double pi = 3.14159;
const_cast

该运算符用来修改类型的 const 或 volatile 属性。除了 const 或 volatile 修饰之外, type_id 和 expression 的类型是一样的。常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

  const_cast<type_id> (expression)

dynamic_cast

dynamic_cast(动态转换),允许在运行时刻进行类型转换,从而使程序能够在一个类层次结构安全地转换类型。dynamic_cast 提供了两种转换方式,把基类指针转换成派生类指针,或者把指向基类的左值转换成派生类的引用。

enum

enum(枚举)类型,给出一系列固定的值,只能在这里面进行选择一个。

explicit explicit(显式的)的作用是"禁止单参数构造函数"被用于自动型别转换,其中比较典型的例子就是容器类型。在这种类型的构造函数中你可以将初始长度作为参数传递给构造函数。
export 为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准 C++ 新增加的关键字 export(导出)。
extern

extern(外部的)声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义(实现)。在文件内声明一个变量或函数默认为可被外部使用。在 C++ 中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前仅支持 C 转换标记,来支持 C 编译器链接。使用这种情况有两种形式:

extern "C" 声明语句 extern "C" { 声明语句块 }
goto

goto(转到),用于无条件跳转到某一标号处开始执行。

inline inline(内联)函数的定义将在编译时在调用处展开。inline 函数一般由短小的语句组成,可以提高程序效率。
namespace namespace(命名空间)用于在逻辑上组织类,是一种比类大的结构。
new new(新建)用于新建一个对象。new 运算符总是返回一个指针。由 new 创建
sizeof 由于 C++ 每种类型的大小都是由编译器自行决定的,为了增加可移植性,可以用 sizeof 运算符获得该数据类型占用的字节数。
struct struct(结构)类型,类似于 class 关键字,与 C 语言兼容(class 关键字是不与 C 语言兼容的),可以实现面向对象程序设计。
template template(模板),C++ 中泛型机制的实现。
typedef

typedef(类型定义,type define),其格式为:

typedef 类型 定义名;

类型说明定义了一个数据类型的新名字而不是定义一种新的数据类型。定义名表示这个类型的新名字。

typeid 指出指针或引用指向的对象的实际派生类型。
typename

typename(类型名字)关键字告诉编译器把一个特殊的名字解释成一个类型。在下列情况下必须对一个 name 使用 typename 关键字:

  • 1. 一个唯一的name(可以作为类型理解),它嵌套在另一个类型中的。
  • 2. 依赖于一个模板参数,就是说:模板参数在某种程度上包含这个name。当模板参数使编译器在指认一个类型时产生了误解。
union union(联合),类似于 enum。不同的是 enum 实质上是 int 类型的,而 union 可以用于所有类型,并且其占用空间是随着实际类型大小变化的。
unsigned unsigned(无符号),表明该类型是无符号数,和 signed 相反。
using 表明使用 namespace。
volatile

volatile(不稳定的)限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:

int volatile nVint;

这样的声明是不能达到最高效的,因为它们的值随时会改变,系统在需要时会经常读写这个对象的值。因此常用于像中断处理程序之类的异步进程进行内存单元访问。

wchar_t

wchar_t 是宽字符类型,每个 wchar_t 类型占 2 个字节,16 位宽。汉字的表示就要用到 wchar_t。

   

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

四、强制类型转换运算符

   1、当不同类型的量 进行混合算术运算时,系统自动进行合理的类型转换,也可以在程序中使用强制类型转换运算符。

      系统自动转换 原则: 低字节向高字节转换   

      int a;    double b;  a+b --> 结果为double类型  ;int 类型4个字节,double 8个字节,低字节向高字节转换。

   2、static_cast用于将一种数据类型转换成另一种数据类型,一般情况下,static_cast可以缺省。

        static_cast <类型名> 表达式

#include <iostream>
using namespace std; int main() { double a = 34.23; cout << (int)a << endl; cout << int(a) << endl; cout << static_cast<int> (a) << endl; return 0; }

结果:

34
34
34 

   3、const_cast用于去除 指正引用的 常量性,但不能去除 变量的 常量性

        const_cast<类型名> (表达式)

    功能是将 常量指针转化成 非常量的指针,并且仍然指向 原来的对象

    或是将 常量引用 转换成 非常量的引用,并且仍然指向原来的对象

 

  代码示例: 

#include <iostream>
using namespace std; int main() { int a = 10;                // 定义整型变量 a
    const int *p = &a;        // 定义指针变量 p,存储变量a的地址,因此 *p便是a的值。
    const int ca = 30;        //定义整型 ca,用const定义,表示变量的值不许改变。
    int *q;                    //定义整型指针q
 cout << "a的地址为:\t" << &a << "\t a的值为: \t" << a << endl; cout << "p指向的地址为:\t" << p << "\t *p的值为:\t" << *p << endl; q = const_cast<int*> (p);    //去除p的常量性 赋值给q,如果写p=q 则会报错。
    *q = 20; cout << "a的地址为:\t" << &a << "\t a的值为: \t" << a << endl; cout << "p指向的地址为:\t" << p << "\t *p的值为:\t" << *p << endl; cout << "q的地址为:\t" << q << "\t *q的值为: \t" << *q << endl; cout << "——————————\t" << endl; p = &ca;                //ca的值不能修改
    q = const_cast<int*> (p);    //去除p的常量性 赋值给q。
    *q = 40; cout << "ca的地址为:\t" << &a << "\t ca的值为: \t" << a << endl; cout << "p指向的地址为:\t" << p << "\t *p的值为:\t" << *p << endl; cout << "q的地址为:\t" << q << "\t *q的值为: \t" << *q << endl; system("pause");        // 让程序停下,按任意键继续
    return 0; }

结果:

 

 

 

五、函数参数的默认值

  1、在C++语言中,可以在声明函数时为形参指定默认值。
  2、在C++定义函时,只能为函数最后面的连续若干个参数设置默认值,且在调用处也只能缺省后面的 连续若于个实参。
    提供默认值时必须 按从右至左的顺序提供,既有默认值的形参必须在形参列表的最后
  例:
    void defaultvalue1(int=2,double=3.0) ;//正确
    void defaultvalue2(int a, double b=3.0);//正确
    void defaultvalue3(int a=2, double b);//错误
    void func1(int a, int b=2,intc=3); //正确
    void func2(int a=1, int b, int c=3);//错误
    void func3(int a=1,int b=2,int c);//错误
  3、函数参数的默认值可以写在声明函数的地方,也可以写在定义函数的地方,但不能在两个地方都写。

 

 

六、引用和函数参数的传递

   1、引用的定义

    * 引用相当于给变量起一个别名。变量对应于某个内存地址,如果给某个变量起了别名,相当于变量和引用都对应到同一个地址。

      “引用”的定义格式:

      类型名  &引用名 = 同类型的某变量名;

               

 

 

     * 系统并不为引用变量分配空间,引用变量与原变量对应的是同一个内存地址,也就是“你变,我就变,我变,你也变”

     * 声明引用变量时,原变量必须初始化。

     * 不能有 空引用,即 引用必须指向 某个已存在的内存区域的首地址,也不能声明引用的引用。如: int &c = &b; ×

int main() { int oneInt = 1; int& ref = oneInt; const int& refc = oneInt; ref = 2; cout << "oneInt=" << oneInt << "," << "ref=" << ref << endl; cout << "refc=" << refc << endl; int& ref2 = ref; cout << "ref2=" << ref2 << endl; return 0; }

结果:
oneInt=2, ref=2 refc=2 ref2=2

 

  2、引用在函数中的使用

    引用既可以作为函数的参数使用,也可以作为函数的返回值使用。 C++中,函数调用时参数的传递有两种方式:传值传引用

    •  传值,传递对象的值

      如果函数的形参不是引用,那么调用时 实参传递给形参 通常采用的时传值的方式,即 将实参的值拷贝给形参,

  函数内部对形参的改变不会影响到函数外实参的值

 这里a,b为局部变量,只是将 a,b的值拷贝给了 形参,但并不影响实参a,b的值,所以结果是a=12,b=18.

 

    • 传引用,传递对象的首地址值    

       如果函数的形参是引用,则调用时实参传递给形参采用的是传引用的方式。函数调用时,实参对象名传递给形参对象名,形参对象名就成为实参对象名的别名,

    即形参是对应实参的引用,他们是等价,代表同一个对象,也可以看作是将实参的地址传递给了形参。

      在函数内部对形参的操作,都是对这个地址的内容进行的,相当于对实参的值进行了操作。所以当函数执行完毕返回后,实参的变化被保留下来。

 

 这里的a,b是局部变量,&a引用a,因此b赋值给a的引用,a本身也发生了改变。

 

 

    • 引用作为函数返回值

       int & fun(int &c){...}

      函数的返回值是一个引用,所以可以作为赋值语句中的左值使用。

                      即:a 与 x 与 fun(a) 的值都是同一个

 

 

 

 

 

 

 七、const与指针共同使用

  1、const修饰指针变量时,基本含义:

    1)如果唯一的const位于符号*的左侧(const int *p = &a;),表示指针所指数据是常量,数据不能通过本指针改变,但可以通过其他方式进行修改;指针本身是变量,可以指向其他的内存单元。

    2)如果唯一const位于符号*右侧(int * const p = &a;),表示指针本身是常量,不能让该指针指向其他内存地址;指针所指的数据可以通过本指针进行修改。

    3)在符号*的左右各有一个const时,表示指针和指针所指数据都是常量,既不能让指针指向其他地址,也不能通过指针修改所指向的内容。

    const int * p = &a;  //指向常量的指针

 

     

    int * const p = &a;  //常量指针

 

    const int * const p = &a;  //指向常量的常量指针

 

 

 

 

 

 

 九、函数的重载

   函数重载,是指在程序的同一范围内声明几个功能类似的同名函数

      ①参数个数不同;  ②参数类型不同;    ③不可以通过函数的返回值类型区分调用  --> 

                    int same(int,double);  double same(int ,double;)  无法通过返回值类型来区分是调用的哪一个,所以这两个不是重载。

 

十、指针和动态内存的分配

  1、指针变量中保存的是一个地址,也成指针指向一个地址。

  2、关于空间分配:

    • 静态内存分配
      •   编译时确定数组空间大小的方式。
    • 动态内存分配
      •   在程序运行期间,根据实际需要,临时分配一段内存空间用于存储数据。在C++中,使用new运算符实现动态内存分配。       p = new T;
      •   使用new运算符还可以动态分配一个任意大小的数组;  p = new T[N];

  

  3、使用new运算符动态申请的内存空间,需要在使用完毕后释放。C++提供了delete运算符,用来释放动态分配的内存空间。

    delete运算符的基本用法:

          delete 指针;      delete []指针;  

 

 

十一、用string对象处理字符串

1、C++标准模板库中提供了string数据类型,专门用于处理字符串。string是一个类,这个类型的变量 称为“string对象”。

2、要在程序中使用string对象,必须在程序中包含头文件string,即在程序的最前面,要加上如下语句: #include<string>

3、声明一个string对象,与声明普通变量是类似
string变量名
在声明string变量的同时,也可以进行初始化。既可以使用字符串常量进行初始化,也可以使用另一个 字符串变量进行初始化。
4、 string对象可以使用cin和cout进行输入和输出,还可以使用运算符“+”进行连接。

 

 

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM