一、C++的标准输入输出流
1、基本输入输出
cpp
#include <iostream> //必须添加头文件
标准输入(standard input)与预定义的istream 对象cin对应 scanf
标准输出(standard output) 与预定义的ostream对象cout对应 printf
标准出错(standard error)与预定义的的ostream对象cerr对应 perror
标准出错 ostream clog; 标准出错 出错日志输出 ,错误级别比较高
标准输出:cout 标准输入:cin 标准出错:cerr ,这三个都是类对象。
初步理解类把他当成一个结构体类型,那么类对象就是结构体变量。
C++里面是通过三个类对象实现 输出 输入 出错的。
分别是 cin cout cerr clog 都是属于 std作用域中的。
所以在使用它们的时候,需要 std::cin 或 std::cout 或 std::cerr
2、标准输入 cin (c指的是c++,in指的是input)
cpp
C的东西,C++有,C++有的,C不一定有.
cin>>变量 ----不需要指定类型(基本数据类型是自动识别)
比如:从键盘上获取一个整数 和 字符串,并且输出
3、标准输出 cout (c指的是c++ ,out指的是output)
cpp
cout<<变量/常量 ---不需要指定类型(基本数据类型是自动识别)
//将指定的数据输出(<<)到标准输出设备(屏幕终端)上
std::cout<<"val:"<<val<<std::endl;在使用的时候,用std::指明cout 是 来自std命名空间
std::cout<<"str:"<<str<<std::endl;
std::endl 代表换行 相当于 "\n"
当然可以不建议这么写:std::cout<<"str:"<<str<<"\n";
特点:cout会自动识别数据类型来输出,而且可以支持连续输出
注意(容易出错的地方):
① 现在使用cout、cin、endl一定要加上std命名空间:std::cin 、std::cout、std::endl
② 在使用的时候 重载运算符 << >> 不要写反了
③ 在使用cin标准输入的时候,不能在后面加std::endl; 即 std::cin>>val>>std::endl; ---错误
4、完整例子:
cpp
#include<iostream>
int main()
{
char name[256]={0};
int age;
float score;
std::cout<<"请输入姓名 年龄 分数:";
std::cin>>name>>age>>score;
std::cout<<"姓名:"<<name<<" 年龄:"<<age<<" 分数:"<<score<<std::endl;
return 0;
}
二、string类型(C++语法特性之一,C没有的)
1、基本概念引入
cpp
C++是C的升级拓展,所以C++的基本变量类型和C是一样的,
但是C++语法中具有一个特殊的类型就是string类类型。string这个类型是C++的std提供的,
所以使用的时候需要std::string.
string类型的理解:用来存放字符串的类型数据,是C++独有的类型,
不像C需要定义字符数组,
例如下面的例子:
需要#include <string>
字符串初始化:
string str_1 = "abc";
字符串赋值:
string str_2; //定义
str_2 = "dfasdfasd";//赋值
字符串复制: string s2 = s1; //把上面的字符串s1复制给s2 C strcpy
字符串拼接: string s3 = s1+s2; 这里是非裸加,
当然也可以裸加。 string s4 = "fdsaf" + "fdsaf"; C strcat
字符串对比: if(s1 == "dfs") // 而 C是用函数:strcmp
cpp
注意:
string s2, s3;
s2 = "hello";
s3 = "world";
string s1 = "你" + "好"; //这里会报错,因为不能识别两个字符串类型为string
而这样是可以的
string s1 = s2 + "世界";
2、string类中的find函数
1:find函数的功能
是在一个字符串中查找是有指定的子串,string是一个__类__,所以它里面可以有函数,它里面有一个find函数,类中的函数是被 类对象 使用的。
2:find函数的语法
cpp
头文件:#include <string>
字符串检索子串: size_t find(const string str, size_t pos = 0);
形参1: 字符串对象 --- 作为子串
形参2: pos:是要在母串中哪一个位置开始找
str:你要找的子串
函数返回 子字符串 在 母字符串 中的下标位置,
如果找到则返回第一个匹配的位置,
如果没有找到则返回-1 string::npos(一个常量值,表示未找到)。
3:find的例子
cpp
#include <iostream>
#include <string>
int main()
{
// 定义两个类的对象
std::string s1, s2;
std::cout<<"请输入一个母串";
std::cin>>s1;
std::cout<<"输入需要查找的字串";
std::cin>>s2;
//在s1的母串中find字串,返回值为s1查找到的下标值
size_t pos = s1.find(s2, 0); //这个是动态的(因为有定义s1的类对象)
if(pos == std::string::npos) //std::string::npos为静态(即没有定义类对象直接使用类成员)
{
std::cout<<"没查找到"<<std::endl;
}
else
{
//将查找的字串的位置输出来
std::cout<<"字串在s1的位置下标为:"<<pos<<std::endl;
}
return 0;
}
运行结果:

3、string中常见的成员函数
有⭐是比较重要的
cpp
构造函数:经过函数重载
string(): 创建一个空字符串。
string(const string& str): 创建一个字符串副本。 string s1 = "hello"; string s2(s1);
string(const char* s): 从 C 风格字符串创建一个字符串。 string s1("hello");
string(size_t n, char c): 创建一个字符串,长度为 n,并用字符 c 填充。 string s1(10,'o');
void clear(): 清空字符串内容。⭐
bool empty() const: 判断字符串是否为空。⭐
void push_back(char c): 在字符串末尾添加一个字符。⭐
void pop_back(): 删除字符串的最后一个字符。⭐
void append(const string& str): 在字符串末尾追加另一个字符串。
void append(const char* s): 在字符串末尾追加 C 风格字符串。
char& at(size_t pos): 获取指定位置的字符,若位置越界,则抛出 out_of_range 异常。 ⭐
进行内存边界检查
char& operator[](size_t pos): 获取指定位置的字符(可以修改)。
4、常见的例子
问题:给定一个字符串,判断它是否是回文字符串。回文字符串是指正着读和反着读都一样的字符串。 eg:heeh
cpp
#include <iostream>
#include <string>
using namespace std;
bool ishuifen(string s1);
bool ishuifen(string s1)
{
int str_len = s1.length();
for(int index=0; index < str_len/2; index++)
{
if(s1.at(index) != s1.at(str_len - 1 - index))
{
return false;
}
}
return true;
}
int main()
{
string s1;
while(1)
{
cout<<"请输入一个字符串s1:"<<endl;
cin>>s1;
if(ishuifen(s1) == false)
{
cout<<"不是回文"<<endl;
}
else
{
cout<<"是回文"<<endl;
}
}
return 0;
}
运行结果:

三、C++指针和动态内存(堆)
1、对于指针变量的写法,C++编译平台更为严格,例如
cpp
用来存储地址的变量,在C语言中,如果地址类型不一致,只会报警告,
而在C++中会更为严格会直接报错,所以在C++中类型必须要一致。
比如:
在C语言中
int *p = 0x12345678; //左边是int*类型,右边是int类型,类型不一致会警告
在C++中
int *p = 0x12345678;会直接报错
必须强转为相同类型
int *p = (int*)0x12345678;
2、动态内存的申请和释放
cpp
c语言方式 --函数
申请堆空间 malloc, calloc realloc
释放堆空间 free
c++语言方式 ---运算符(或者也可以说是关键字)
申请堆空间 new =====》 malloc
释放堆空间 delete ===》 free
1)申请格式和释放格式
cpp
new的申请格式:
数据类型 *变量名 = new 数据类型;//默认只会申请一个单位堆空间,至于多少字节根据数据类型确定
数据类型 *变量名 = new 数据类型(初始值); //申请内存空间的时候直接初始化
数据类型 *变量名 = new 数据类型[数据元素个数];
数据类型 *变量名 = new 数据类型[数据元素个数]{,,,,};//申请n个单位,并且初始化n个单位的值
int * int_p = (int *)malloc(sizeof(int));
int * int_p = new int; //跟上面C的效果一样
int * int_p = (int*)malloc(sizeof(int)*4);
int * int_p = new int[4]; 总共申请16个字节,4个整形的堆空间, //跟上面C的效果一样
释放格式:
delete 指针变量; 释放单个对象
delete []指针变量; 释放连续的多个对象
例如:
cpp
char *p = new char; 申请一个char对象空间 1个字节
char *p = new char('a'); 申请一个char对象并且初始化为a
char *p = new char[100] ; 申请100个char对象(空间是连续) ---数组
char *p = new char[100]{"初始化"}; 申请100个char对象(空间是连续的)并且初始化
int (*p)[5] = new int[4][5]; 给一个数组指针变量p申请空间,申请4个数组,数组长度为5
int *p = new int[5]; 申请5个int对象(空间是连续) ---数组
完整例子:
例子1:
cpp
#include <iostream>
int main()
{
int *p = new int; //这里是申请一个单位的堆空间
*p = 12;
std::cout<<*p<<std::endl;
delete p; // 释放堆空间
return 0;
}

例子2:
cpp
#include <iostream>
int main()
{
int *p = new int[6]; //这里是申请6个int单位的堆空间
for(int index=0; index<6; index++ ) // 逐个赋值
*(p + index) = index;
for(int index=0; index<6; index++ ) // 逐个输出
std::cout<<"p["<<index<<"]="<<*(p+index)<<std::endl;
delete []p; // 释放堆空间
return 0;
}

3、动态内存的总结
cpp
C语言中的malloc free 是函数,C++语言中的new delete是运算符.
基本总结:
申请
new 类型; 至少一个对象空间
new 类型[对象个数]; 申请多个对象空间
new 类型[对象个数]{初始化值}
new 类型{初始化值}
释放
释放一个对象 delete 指针变量;
释放多个对象 delete []指针变量 ;
拓展总结:
new和malloc的区别:
new 在申请内存的同时,还会调用对象的构造函数(初始化),而 malloc 只会申请内存;
同样,delete 在释放内存之前,会调用对象的析构函数,而 free 只会释放内存。
类中有两个基本必备的函数 构造函数 + 析构函数
new的构造函数的作用是帮你初始化new出来的空间的值
delele的析构函数的作用是帮你释放new出来的空间
后面还有几个语法有空补上