记录自己学习C++的过程,编译环境Visual Studio 2019
目录一
一.C++语言概述
1.C和C++
①C和C++都是编译型语言
②C和C++都是强类型语言,但是C++更强
③C++去除了C语言一些不好的特性
④C++增加了很多C语言中没有的好的语法特性,支持面向对象编程,比C语言更适合大型软件的开发。
二.第一个C++程序
#include <iostream>
//#include <stdio.h>//C风格
#include <cstdio>//C++风格
int main(void)
{
std::cout << "The first C++ program!" << std::endl;
printf("The first C++ program!\n");
return 0;
}
1.文件扩展名
① .cpp //推荐
② .cc
③ .cxx
④ .C
2.头文件
#include
1)C++中所有和I/O相关的类型、对象、函数都在该头文件中
2)C++中多数头文件没有".h"后缀
3)C++开发中也可以使用标准C库的头文件,同时提供一套不带".h"替换版本
#include <stdio.h> <==> #include <cstdio>
#include <stdlib.h> <==> #include <cstdlib>
#include <string.h> <==> #include <cstring>
3.标准输入、输出
①使用cin对象表示标准输入//类似scanf()
eg.
int a = 0;
scanf("%d",&a);//C语言
cin >> a;//C++语言
//注:“>>”成为输入操作符
---------------------------
int i = 0,double d = 0.0;
scanf("%d%lf",&a,&d);//C
cin >> a >> d;//C++
②使用cout对象表示标准输出//类似printf()
eg.
int a = 123;
printf("%d\n",a);//C语言
cout << a << endl;//C++语言
//注:“<<”被称为输出操作符
---------------------------
int i = 100,double d = 2.34;
printf("%d,%lf\n",i,d);//C语言
cout << i << ',' << d << endl;//C++语言
三.名字空间(命名空间)
1.名字空间作用
①避免名字冲突
②划分逻辑单元
eg.
#include <iostream>
using namespace std;//标准名字空间指令
namespace ns1{
void func(void){
//std::cout << "ns1的func" << std::endl;
cout << "ns1的func" << endl;
}
}
namespace ns2{
void func(void){
//std::cout << "ns2的func" << std::endl;
cout << "ns2的func" << endl;
}
}
int main(void){
//名字空间成员不能直接访问
//func();//error
//可以通过"::"来访问
ns1::func();//ns1的func
ns2::func();//ns2的func
return 0;
}
2.定义名字空间
namespace 名字空间名{
名字空间成员1;
名字空间成员2;
...
}
(注:名字空间的成员可以是全局变量、全局函数、类型、名字空间)
eg.
#include <iostream>
using namespace std;//标准名字空间指令
namespace ns1{
void func(void){
cout << "ns1的func" << endl;
}
}
namespace ns2{
void func(void){
cout << "ns2的func" << endl;
}
}
int main(void){
using namespace ns1;//名字空间指令
func();//ns1的func
using namespace ns2;//名字空间指令
//func();//歧义错误
ns2::func();//ns2的func
return 0;
}
3.名字空间成员的使用
①通过作用域限定符号“::”访问
名字空间名::要访问的成员;
eg:"std::cout",访问std标准名字空间里面的输出流对象cout
②名字空间指令
using namespace 名字空间名;
注:在该条指令以后的代码中,指定名字空间的成员都可见,可以直接访问,省略"名字空间名::"
③名字空间声明
using 名字空间名::要访问的成员;
注:将名字中的特定成员引入到当前声明的作用域中,在该作用域访问这个成员,就如同访问自己的成员一样,可以直接访问,省略"名字空间名::"
eg.
#include <iostream>
using namespace std;//标准名字空间指令
namespace ns1{
void func(void){
cout << "ns1的func" << endl;
}
int num = 100;
}
namespace ns2{
void func(void){
cout << "ns2的func" << endl;
}
int num = 200;
}
//int num = 300;//全局作用域
namespace{//无名名字空间
int num = 300;
}
int main(void){
/*
using ns1::func;//名字空间声明
func();//ns1的func
//using ns2::func;
//func();//歧义错误
using namespace ns2;//名字空间指令
func();//ns1的func,局部优先
ns2::func();//ns2的func
*/
cout << num << endl;//300
using ns1::num;//名字空间声明
cout << num << endl;//100,局部优先
cout << ns2::num << endl;//200
cout << ::num << endl;//300
return 0;
}
4.全局作用域和无名名字空间(了解)
①没有放在任何名字中的成员,属于全局作用域,可以直接访问,但如果和局部作用域的成员一样,将优选访问局部作用域的,这时如果还希望访问全局作用域的成员,可以通过"::xx"显式指明
②定义名字空间时可以没有名字,即为无名名字空间(匿名空间),无名空间的成员全局作用域成员类似,只是被限制在当前文件中使用。
5.名字空间嵌套(了解)
eg.
namespace ns1{
int num = 100;
namespace ns2{
int num = 200;
namespace ns3{
int num = 300;
}
}
}
cout << ns1::num << endl;//100
cout << ns1::ns2::num << endl;//200
cout << ns1::ns2::ns3::num << endl;//300
6.名字空间合并(了解)
//1.cpp
namespace ns{
void func1(void){...}
}
//2.cpp
namespace ns{//自动和1.cpp的合并到一起
void func2(void){...}
}
四.C++的结构体、联合体和枚举
1.C++结构体
①当定义结构体变量时可以省略struct关键字
②结构体里可以定义函数,成为成员函数(方法),在成员函数里面可以直接访问结构体中的其它成员。
访问结构体中的成员用. class.xx
访问指针中的成员用-> class->xx
C++的结构体中还能包含函数, C不能
#include <iostream>
using namespace std;//标准名字空间指令
struct Teacher{
//成员变量
char name[20];
int age;
double sal;
//成员函数
void print(void){
cout << "姓名:" << name << ",年龄:" <<
age << ",工资是:" << sal << endl;
}
};
int main(void){
/*struct*/Teacher Zhangsan={"张三",45,800.5};
wangjl.print();
Teacher* pt = &Zhangsan;
pt->print();
return 0;
}
2.C++联合体
①当定义联合体变量时可以省略union关键字
②支持匿名联合
#include <iostream>
using namespace std;
int main(void){
union{//匿名联合
unsigned int ui;
unsigned char uc[4];
};
ui = 0x12345678;
for(int i=0;i<4;i++){
//hex:以十六进制方式打印
//showbase:显示进制标识
cout << hex << showbase << (int)uc[i]
<< ' ';
}
cout << endl;
return 0;
}
3.枚举
①定义枚举变量时可以省略enum关键字
②C++中枚举被看作是独立数据类型,不能把枚举变量当做int变量使用
#include <iostream>
using namespace std;
int main(void){
enum Color{RED,BLUE,YELLOW};
cout << RED << ',' << BLUE << ',' << YELLOW
<< endl;
/*enum*/ Color c;
//c = 1;//C:ok,C++:error
c = BLUE;//C:ok,C++:ok
cout << c << endl;//1
return 0;
}
五.字符串
1.C语言中字符串
①字面常量字符串: “hello”
②字符指针: char*
③字符数组:char[]
2.C++中string类型
C++中兼容C语言的字符串,另外还增加了一个string类型,专门表示字符串:
①定义字符串
string s;//定义空字符串
string s = "hello";//定义同时初始化
-------------------------
//和上面写法结果等价
string s("hello");
string s = string("hello");
②字符串拷贝:=
string s1 = "hello";
string s2 = "zhangsan";
s1 = s2;//拷贝
cout << s1 << endl;//"zhangsan"
③字符串连接:+ +=
string s1 = "zhang";
string s2 = "san";
string s3 = s1 + s2;//连接
cout << s3 << endl;//"zhangsan"
④字符串比较:== != > < >= <=
if(s1 == s2){...}
if(s1 != s2){...}
⑤随机访问:[]
string s = "helloworld";
s[0] = 'H';
s[5] = 'W';
cout << s <<endl;//"HelloWorld"
⑥常用的成员函数
size()/length();//获取字符串长度
c_str();//返回C风格的字符串(const char*)
-----------------------------------------
string s = "hello";
cout << s.size() << endl;//5
cout << s.length() << endl;//5
-----------------------------------------
string cpp_s = "abc"; //C++风格
const char* c_s = "def"; //C风格
//根据向下兼容,C++字符串是兼容C的,但C不兼容C++
cpp_s = c_s;//ok
c_s = cpp_s;//error
c_s = cpp_s.c_str();//ok
练习
1.练习1:使用string类型表示字符串,从键盘读取一个字符串统计里面包含字符’H’/'h’个数;
输入:“hellohhHHworld” 输出:5
#include <iostream>
using namespace std;
int main(void)
{
string keyboard;
cout << "请输入一个字符串:";
cin >> keyboard; //碰到空白符号或者换行符\n结束,可以使用getline(cin,keyboard)
int num = 0;
for (int i = 0; i < keyboard.size(); i++)
{
if (keyboard[i] == 'H' || keyboard[i] == 'h')
{
num++;
}
}
cout << "你输入的字符串中包含字符'H'/'h'个数是:" << num << endl;
return 0;
}
2.练习2:使用string类型表示字符串,从键盘读取一个字符,反转并打印输出;
输入:“hello” 输出:“olleh”
#include <iostream>
using namespace std;
int main(void)
{
string keyboard;
cout << "请输入一个字符串:";
cin >> keyboard;
int L = keyboard.size();
for (int i = 0; i < L/2; i++)
{
/*char temp;
temp = keyboard[i];
keyboard[i] = keyboard[L - i - 1];
keyboard[L - i - 1] = temp;*/
//下面这种用异或位运算的更高效
keyboard[i] = keyboard[i] ^ keyboard[L - i - 1];
keyboard[L - i - 1] = keyboard[i] ^ keyboard[L - i - 1];
keyboard[i] = keyboard[i] ^ keyboard[L - i - 1];
}
cout << "经过反转后你输入的字符串为:" << keyboard << endl;
return 0;
}