===================================================================
推荐书籍:
《C++程序设计与实现》Bjarne Stroustrup 本贾尼·斯特劳斯特卢普
《C++ Primer》 可读性不太好
C语言思想:把一个大的问题拆解成很多小的问题,然后逐一解决;
C++语言思想:先对问题整体有一个描述,再解决细节;
===================================================================
一、C++语言概述
1、历史背景
1)C++江湖地位
java、C、C++、Python、C#
2)C++之父 Bjarne Stroustup(1950~)
1979,Cpre,为C语言增加类的机制;
1983,发布全新语言C with class,后来命名为C++;
1985,CFront1.0(C++编译器),《The C++ programming Language》;
3)C++发展过程
1987,GNU支持C++
1990,Borland C++(BC)
1992,Microsoft C++(VC)
1998,ISO C++98
2011,ISO C++11/C++0x(在0几年草案已经公布)
2、应用领域
1)游戏开发
2)科学计算
3)网络通信(ACE - 网络库)
4)操作系统和设备驱动
5)其它(嵌入式、编译器、脚本引擎…)
3、C和C++比较
1)都是编译型语言
2)都是强类型语言,但是C++更强(强:int a = 100; 弱:a = 100;)
C++类型检查更加严格
3)C++去除了C中不好特性(test.c)
4)C++中增加很多号的特性(面向对象语法),比C语言更适合大型软件开发;
二、第一个C++程序
1、编译方式
1)$ gcc xx.cpp -lstdc++
2)$ g++ xx.cpp
g++自动链接标准C++库
2、文件扩展名
1)xx.cpp //推荐使用
2)xx.cc
3)xx.C
4)xx.cxx
3、头文件
#include <iostream>
#include <stdio.h>
==> #include <cstdio>
(仅适用与标准C库)
头文件位置:/usr/include/c++/
4、标准输入和输出
1)cin对象表示标准输入 //类似scanf
eg:
int a;
scanf("%d", &a);
cin >> a; //从标准输入设备提取一个整形数放到变量a中;">>":提取运算符
eg:
int a;
double d;
//scanf("%d%lf", &a, &d);
cin >> a >> d;
2)cout对象表示标准输出 //类似printf
eg:
int a = 100;
//printf("%d\n", a); //把数据a插入到标准输出设备;
cout << a << endl; //"<<":插入运算符
eg:
int a = 100;
int d = 3.14;
//printf("%d %lf\n", a, d); //100 3.14
cout << a << " " << d << endl; //100 3.14
三、名字空间(namespace)
1、名字空间的作用
1)避免名字冲突
2)划分逻辑单元
2、定义名字空间
namespace 名字空间名{
名字空间成员1;
名字空间成员2;
...
}
eg:
namespace ns1{
int x; //全局变量
void func(){} //全局函数
struct A{}; //自定义类型
namespace ns2; //名字空间
}
3、名字空间的使用
1)通过作用域限定符 “::”
名字空间名::访问的成员
eg:
int main(void)
{
//访问ns1名字空间中x变量
x = 100; //error,名字空间里面成员不能直接访问
ns1::x = 100; //ok
func(); //error
ns1::func(); //ok
}
eg:
/* std是标准C++库中已经定义好的名字空间,称为标准名字空间,所有C++库中全局函数、全局变量都在该名字空间中。 */
std::cout << "hello world" << std::endl;
2)名字空间指令
using namespace 名字空间名;
在该条指令以后的代码中,指定名字空间中的成员都可见,访问其中成员可以省略作用域限定。(相当于全局变量)
eg:
using namespace std;
int main(void){
cout << "hello world!" << endl;
return 0;
}
3)名字空间声明
using 名字空间名::名字空间成员;
将名字空间中的特定成员引入当前作用域,在该作用域中访问这个成员可以省略作用域限定。(相当于局部变量)
eg:
namespace ns{
int i1;
int i2;
}
int main(){
using ns::i1;
i1 = 100; //ok
i2 = 200; //error
ns::i2 = 200; //ok
}
4、无名名字空间
不属于任何名字空间的全局变量或函数,将被编译器自动放入无名名字空间中。
eg:::无名名字空间成员;
5、名字空间的嵌套(了解)
namespace china{
namespace beijing{
char* name;
}
namespace chengdu{
char* name;
}
}
cout << china::beijing::name << endl;
cout << china::chengdu::name << endl;
四、C++的结构体、联合体和枚举
1、结构体
1)定义结构体变量时,可以省略struct关键字;
2)结构体中里面可以定义函数,称为成员函数,在成员函数中可以访问成员变量;
2、联合体(了解) - - - - 节省内存空间
1)定义联合体变量时可以省略union关键字;
2)支持匿名联合;(只能在局部区使用,不能放在全局区)[本机测试编译不通过]
07union.cpp:13:7: error: conversion from ‘int’ to non-scalar type ‘main()::<anonymous union>’ requested
un = 0x12345678;
^~~~~~~~~~
07union.cpp:16:18: error: ‘uc’ was not declared in this scope printf("%#x ", uc[i]);
3、枚举
1)定义枚举变量时,可以enum关键字;
2)C++枚举看做一种独立数据类型,而C中枚举本质就是整形数。
eg:
enum COLOR{RED, GREEN, BLUE};
COLOR c;
c = 100; //c中ok,c++中error
c = RED; //ok
五、字符串
1、回顾C中字符串
1)双引号常量字符串"hello world"
2)字符串指针:char*
3)字符数组:char arr[..];
eg:
char arr[] = "hello";
strcpy(arr, "xuyeqiang"); //内存越界,危险
char* p = "world"; //const char* p;(p指向的内容不能改变) char* const p;(p的指向不能改变)
strcpy(p, arr); //段错误
p = "xuyeqiang"; //ok
arr = "xuyeqiang"; //error
2、C++兼容C中字符串,同时增加string类型,专门表示字符串
1)定义字符串
#include <string>
string s; //定义一个空字符串
string s = "hello";
string s = string("hello"); //和上面等价
string s("hello"); //和上面等价
cout << s << endl; //cout可以直接输出string类型的字符串
2)字符串的基本操作
运算符 | 基本操作 | 演示 |
+ 或 += | 字符串的连接 | eg1 |
= | 字符串的拷贝 | eg2 |
< 或 <= 或 > 或 >= | 字符串大小的比较 | eg3 |
== 或 != | 字符串是否相同 | |
[] | 获取字符串中指定的字符 | eg4 |
eg1:
string s1 = "hello";
string s2 = "world";
s1 += s2; // s1 = s1 + s2
cout << s1 << endl; // "helloworld"
eg2:
string s1 = "hello";
string s2 = "world";
s1 = s2;
cout << s1 << endl; // "world"
eg3:
string s1 = "hello";
string s2 = "world";
if(s1>s2){
cout << "s1 > s2" << endl;
}
else{
cout << "s1 < s2" << endl; //ok
}
eg4:
string s = "hello";
s[0] = 'H';
3)string类型中常用的成员函数
size() / length() //获取字符串的长度
c_str(); //将string转换为char*风格的字符串
cin >> s; //读字符串,碰到空格、tab、回车则结束
getline(cin, s); //可以读走空格、tab,仅回车时结束