C++尝鲜
#include<iostream>
using namespace std;
int main(){
int num = 0;
cout << "how old are you ?" << endl;
cin >> num;
cout << "you are" << num << " years old" << endl;
return 0;
}
#include<iostream> //引入输入输出流
std::cout //标准输出
std::cout << 变量;
std::cout << 变量 << string << endl; //拼接
std::cout << 变量 << std::endl; //添加换行
std::cin //标准输入
std::cin >> 变量
C++基础
声明和定义变量
- 多个文件使用同一个变量,声明和定义必须分离,且变量的定义只能出现在一个文件中,其他使用到该变量的文件则必须对其声明,不能重复定义
- 头文件 climits定义了基本数据类型的最大最小值符号常量
int x;//声明变量 const int month = 12; //声明常量 extern int i; //若某文件中已声明变量i; int j = 3.14; //定义变量 extern int i = 0; //初始化后的extern标记的变量不再是声明变量而是定义变量
auto关键字
auto根据初始化值的类型推断变量的类型
auto n = 100;
auto x = 1.5 ;
auto str = "kyeleson"
引用(左值引用& 右值引用&&)
int val = 1024;
int &ref_val = ival;
int i = ref_val; i 被初始化为val的值
ref_val指向val
引用即别名,并非引用对象,仅仅为所存在的对象声明一个新名字
引用的初始值必须是一个对象,只能被初始化一次,不可修改
一个变量可以定义多个引用
对引用的操作与对变量的直接操作完全一样,即修改引用ref_val等同于修改val
#include<iostream>
int main(){
int val = 10;
int &ref_val = val;
ref_val = 32;
std::cout << val << std::endl;
getchar();
return 0;
}
结果:32
右值引用->临时对象,绑定到右值,可修改且不会再被利用
利用廉价的移动操作代替昂贵的拷贝操作以此优化性能
string &&str("hello");//右值引用
//旧式swap函数
template <class T>
string swap(T &a ,T &b){
T temp = a;//拷贝a值
a = b;//拷贝b值
b = temp;//拷贝temp值
}
//右值引用版
//temp为右值引用 临时对象
template <class T>
string swap(T &a ,T &b){
//move(x) == static_cast<T&&>(x)
T temp = move(a);//直接读取a右值
a = move(b);//直接读取b右值
b = move(temp);//直接读取temp右值
}
数组
//一维数组
int array[5];
int array[] = { 1,2,3,4 };
double array[4]{ 1.2,3.4,3.2,4.5 }; //C++11
char array[] = { 'a','b','c','\0' };
char array[2] = { 'a','b','\0' };//C风格
char array[2] ={'A','b'}; // C++自动添加'\0'
char str[] = "hello";
//多维数组
int zippo[4][2];
int array[][];//非法
int array[][4];//合法
//声明n维数组时除了最左边的方括号可以留空外,其他都需要填写数值
//zippo == &zippo[0];
//zippo[0] == &zippo[0][0] == zippo;
//zippo和zippo[0]起始于同一地址,具有相同的数值
//*&zippo[0][0] == **zippo == zippo[0][0]
//zippo[2][1] == *(*(zippo+2)+1
字符串 TODO:字符串操作
(字符串处理:直到遇到’\0’才结束)
char array[] = { 'a','b','c','\0' };//C风格
char array[2] = { 'a','b','\0' };//C风格
char array[2] ={'A','b'}; // C++自动添加'\0'
char str[] = "hello";// C++自动添加'\0'
//char[int] 定义的字符串是字符串常量,不可使用直接修改
、、string类
#include<string>
string str = "hello";
str = "world"; //可修改
string str = {"hello world"};
string str{"hello world"};
string c(5, 'A'); //c = "AAAAA"
char dog[8] = {'b','e','a','u','x','','T','T'}; // not a string
char cat[8] = {'f','a','t','a','s','s','a','\0'}; // a string
‘A’:字符常量
“A”:字符串常量,字符’A’+’\0’
C风格字符串的比较需要用到strcmp()函数,字符串变量本身代表的是地址,不能直接使用“=”比较
#include <cstring>
char* first_name = "mate";
char* last_name = "mate";
int code = strcmp(first_name,last_name);
printf("code:%d",code);
结构体
struct person{
char name[20];
int year;
char sex;
};
person p = {"kyleson",19,'男'};
std::cout << p1.name << std::endl;
person *pp = &p;//pp->name == (*pp).name
//C++结构体中可以定义函数 C语言则不可
struct sample{
int a;
int b;
int add() {return a + b;}
};
sample s = { 1,2 };
std::cout << s.add() << std::endl;
每个struct只能有唯一的定义,对于两个struct,即使成员相同其本身仍是不同的类型
struct addr{
int num;
};
addr x;
addr y = x;//错误,类型不匹配
int i = x;//错误,类型不匹配
联合体 union
union是特殊的struct,其所有成员都分配在同一地址空间,即在相同的内存位置存储不同的数据类型,union实际占用的空间大小与其最大的成员相同,并且在同一时刻union只保存一个成员的值
union value{
char sex;
int sex_num;
}
value val;
val.sex = '男';//根据类型需求设置成员及值
枚举
enum Name{…}枚举值隐式转换为整数类型,枚举值名字与枚举本身位于同一作用域
enum color{ red,blue,black,white };
color brand = red;
std::cout << brand << std::endl;
brand = 10;// 错误 非枚举类型
brand = color(blue);
brand = color(4);
int c = red;//隐式转换为int
enum bit{one = 10,two = 22,three};
bit b = three; //three = 23
enum class Name{…}限定作用域的强类型枚举,枚举值不会隐式转换为其他类型,枚举值名字位于枚举局部作用域
enum class Color{red,green,yellow};
Color c = Color::red;//局部作用域
Color color = red;//错误
int c = Color::red;//错误
指定枚举初始类型
enum class color:char{red,green,yellow};
指针 TODO:共享指针,智能指针
(指向对象的对象[存储指向对象的地址],在生命周期内可指向不同的对象)
int *p; //p指向int类型对象的指针
int val = 19;
int *ip = &val;
//ip是指向变量val的指针,存储变量val的地址,此处&:取地址符,非引用
//ip ---> val的地址值
// *ip ---> val的值 42
指针的值(状态):指向一个对象、指向紧邻对象所占空间的下一个位置、空指针、无效指针
利用指针访问对象:操作符 *
int num = 12;
int * p = #
std::cout << *p <<std::endl;
打印结果:12
空指针:不指向任何对象
int *p = nullptr;
int *p =0;
通过new分配内存
int *p = new int;
*p = 10;
std::cout << *p << std::endl;
delete p;
void* 指针:存放任意对象的地址
double pi = 3.14,*pd = &pi ;
void pv = π
pv == pd ? --> true
note:不能直接操作void*指针所指向的对象,对象类型未知
指针的指针:指向指针的指针,存储指针的本身的地址
int val = 1024;
int *p = &val; //指向一个int类型的变量
int **pp = &p;//指向一个int类型的指针变量
指向常量的指针,不允许被修改
const double pi = 3.14;
const double *p1 = π
double *p2 = π// 错误 p2被定义为普通指针
*p1 = 42; //错误 不允许赋值
const指针:常量指针,指针本身也是常量,必须被初始化
int errNum = 0;
int *const curErr = &errNum; //curErr一直指向errNum对象
const double pi = 3.14;
const double *const pip = &pi ;// pip指向常量对象的常量指针
int num = 1;
curErr = # //错误 指向的对象不允许被改变
*curErr = 1; //正确 指向的对象非常量,其值可被修改
*pip = 1; //错误 指向的对象为常量,其值不能被修改
函数指针 指向函数的指针,保存着函数代码起始处的地址
函数:void toUpper(char*);
指向函数的指针:void (*pf) (char*);
pf = toUpper; 函数指针赋值
char mis[6]="hello";
#把toUpper作用于mis
(*pf)(mis);
pf(mis)
bool (*pf)(const string &,const string &)
指针和数组
int array[5] = {1,2,3,4 };
array本身是指向array第一个元素的指针
std::cout<< *array; ---> 1
char array[] = { 'a','b','c','d' };
char str1 = array[0];
char str2 = *array;
char str4 = array[1];
char str3 = *(array +1);
std::cout << str1 << str2 << str3 << str4 << std::endl;
输出:a a b b
char *start = begin(array); //指向array首元素的指针
char *end = end(array); //指向array尾元素下一位置的指针 默认的空字符
int *pts[10]; //pts:含有10个整型指针的数组
int(*ptr)[10]; //ptr:指向(含有10个整型的数组)的指针
char *name = "kyleson";
char str[5] = "ABC";
char *p = str;
int array[] = { 1,2,3 };
int *pa = array;
std::cout << name << *name << *(name + 1) << std::endl;//值: kyleson k y
std::cout << p << *p << std::endl;//值: ABC A
std::cout << pa << *pa << std::endl; //值: 000000F0E032F900 1
std::cout << string ----> (字符串处理:直到遇到'\0'才结束)
类型别名 typedef
typedef double wages; //wages是double的同义词
typedef wages base,*p; //base是wages的同义词,p是double* 的同义词
wage hourly,weekly; //等价于double hourly,weekly;
typedef char* pstr; //复合类型,指向char的指针
const pstr str = 0; //指向char的常量指针,并不是指向常量char的指针
const pstr* ps; //指向[指向char类型的常量指针]的指针
const char* str ;//指向常量char的指针
类型指示符 decltype
decltype(fun()) sum = x ; //sum的类型是函数fun()的返回类型
vector
#include<vector>
vector<string> strs;//定义空集合
vector<string> vetor = {"a","person","hi"};// 列表初始化
vector<int> v_num(10,9); //创建指定数量的元素 每个元素被赋值为9
vector<int> ten_num(10); // 10个元素 每个元素被初始化为0
strs.push_back("hello");//添加元素
TODO:其他集合
存储持续性
自动存储持续性:函数定义中声明的变量/函数参数,其所属函数或代码块执行时被创建,执行完时被被自动释放;
静态存储持续性:函数定义外定义的变量或static修饰的变量,其在整个程序运行中都存在;
动态存储持续性:new分配的内存,直到使用delete释放为止;
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!