C++基础与提高 001

1.综述C++

  1.1. 作者

  1.2. 历史背景

  1.2.1 应“运”而生?运为何?

  1.2.2 C++发展大记事

  1.3. 应用领域

  1.3.1 系统层软件开发

  1.3.2 服务器程序开发

  1.3.3 游戏,网络,分布式,云计算

  1.4. 内容

  C++语言的名字,如果看作C的基本语法,是由操作数C和运算符后++构成。C++是本身这门语言先是C,是完全兼容C,

然后在此基础上++。这个++包含三大部分,C++对C的基础语法的扩展,面向对象(继承、封装、多态),STL等。

  1.5. 书籍推荐

  

     C++ Primer            C++ 编程思想       C++ Priemer Plus

2.C++对C的扩展

 2.1. 类型增强

   2.1.1 类型检查更严格

  比如,把一个const类型的指针赋给非const类型的指针。C语言中可以通的过,但是在C++中则编不过去。  

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     const int a = 100;
 7     int b = a;
 8 
 9     const int *pa = &a;
10     int *pb = pa;
11 
12     return 0;
13 }

error: cannot initialize a variable of type 'int *' with an lvalue of type 'const int *'
int *pb = pa;

 

 1 #include <stdio.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5     const int a = 100;
 6     int b = a;
 7 
 8     const int *pa = &a;
 9     //cannot initialize a variable of type 'int *' with an lvalue of type 'const int *'
10     int *pb = pa;       
11 
12     return 0;
13 }

warning: initializing 'int *' with an expression of type 'const int *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
int *pb = pa;

  动态内存分配C/C++区别:

 1 #include <iostream>
 2 #include <stdlib.h>
 3 #include <stdio.h>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     char *p = malloc(100);    //C中可以这样写
 9     char *q = (char*)malloc(100);    //C中强制类型转换写法
10 
11     char *pt = static_cast<char*>(malloc(200));    //C++中强制类型转换写法  
12 }

  2.1.2 布尔类型(bool)

   C语言的逻辑真假用0和非0来表示。而C++中有了具体的类型(bool flag = true/false;),这样的操作,完全可以使用枚举(enum)实现

   bool类型在内存中大小等于char类型大小。

  2.1.3 真正的枚举(enum)

  虽然C中也有枚举,但是在使用的时候,即使赋值不再枚举的范围内,但是依然是可以执行的,但是在C++中,枚举的值必须在枚举的范围内

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     enum SEASON{
 6         SPA, SUM, AUT, WIN
 7     };
 8 
 9     enum SEASON s = AUT;      
10     enum SEASON r = 100;      //这样也可以在C中,在C++这样是不行的
11     return 0;
12 }

   2.2. 输入与输出(cin cout)

  2.2.1 cin && cout

   

  C中输入典型错误:

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int a;
 8     char c;
 9    
10     scanf("%d%c", &a, &c);
11 
12     return 0;
13 }

  这样输入时变量c会读取不到相应的值,因为在输入时我们往往会输入变量a的之后选择空格或者回车符,而变量c接收了空格或者回车符。所以,变量c读取不到对应的值!!!

  在C++中,不存在上述问题。(cin >> a >> c;)

  注意:

  如果定义一个数组,在用这两种输入方式进行输入的时候,都是不安全的,不能保证输入的长度,例如 char name[30]; 用cin>>name;或者使用scanf("%s",name);的时候,如果输入的字符长度超过30个,那么程序就会出错,不过可以使用fgets(name, 30, stdin);这样就指定最多只能接收29个字符(第30个为'\0'),从而保证了安全性。

  虽然通过接收指定长度的操作可以保证程序的安全性,但是这样可能并不能满足用户的需求,所以C++就创造了string,如果将char name[30];改成string name;那么,这个时候就可以不用考虑因为输入过长而导致程序崩溃的问题了(其实是有一个长度的,不过那个长度已经很大很大了,可以通过name.max_size(),这个函数查看),不过这个时候只能使用cin>>name进行输入,而不能使用scanf这个函数了。

   2.2.2 格式化

  (1) 格式输出的问题

  在C语言中,用pringf进行格式输出,可以通过简单的方法,达到丰富的显示效果,在C++中想要达到相同的效果(如果是使用cout)那还是比较麻烦的。以下是对比:

对比 C语言 C++
设置位宽(n) printf("%nd\n", test);          cout << setw(n) << test << endl;     
左对齐 printf("%-d\n", test); cout << setiosflags(ios::left) << test << endl;   
设置小数点右边位数(n) printf("%.nd\n", test); cout << setprecision(n) << setiosflags(ios:: fixed) << test << endl;    

  (2) 进制的输出

进制           C中参数     C例子                         C++中参数        C++例子    
二进制        
八进制 %o printf("%o", 100);  oct cout << oct << 100 << endl;
十进制      默认   dec cout << dec << 100 << endl;
十六进制     hex cout << hex << 100 << endl;          
设置进制     setbase() cout << setbase(16) << 100 << endl;       

     setbase()参数有指定,如八进制、十六进制

  (3)  还可以设置域宽的同时,设置左右对齐及填充字符

1 int main()
2 {
3     cout << setw(10) << 1234 << endl;
4     cout << setw(10) << setfill('0') << 1234 << endl;
5     cout << setw(10) << setfill('0') << setiosflags(ios::left) << 1234 << endl;
6     cout << setw(10) << setfill('-') << setiosflags(ios:: right) << 1234 << endl;
7 
8     return 0;
9 }

 练习:

  时、分、秒的计时器,从00:00:00开始计时,每过一秒计时增加一秒, 秒加到六十时分钟加一,秒又从零开始加;分钟加到六十时小时加一,分钟又从零开始加;小时加到24时,计时器清零变为00:00:00.如此循环计时!!!

 2.3 函数重载

  2.3.1 引例 

  2.3.2 重载规则与调用匹配(overload&match)

   重载规则:

    1. 函数名相同。

    2. 参数个数不同,参数的类型不同,参数顺序不同,均可构成重载。(只要满足其一即可)

    3. 返回值类型不用则不可以构成重载。

   匹配原则:

    a.严格匹配,找到则调用

    b.如果严格匹配找不到,通过隐式转换寻求一个匹配,找到则调用

      注:C++允许,int 到 long 和 double隐式类型转换。double 向 int 和 float进行隐式转换的时候会出现二义性(ambiguous)

    解决方案:在调用时强转。

   2.3.3 重载底层实现(name mangling)

    C++利用name mangling(倾轧)技术,来改变函数名,区分参数不同的同名函数。

    实现原理:用v c i f l d 表示 void char int float long double 及其引用。 

1 void func(char a);    //func_c(char a)
2 void func(char a, int b, double c);    //func_cid(char a, int b, double c)

    C++的编译方式同C语言,

   2.3.4 extern "C"

    name mangling 发生在两个阶段,.cpp 编译阶段, 和 .h 的声明阶段。只有两个阶段同时进行,才能匹配调用。

    轻轧操作在定义和调用的时候被使用(要么都轻轧,要么都不要轻轧,所以C的库中都使用了extern "C") 

     

 

posted @ 2017-11-17 09:29  忘记过去?  阅读(916)  评论(0编辑  收藏  举报