cin从标准输入中一次读入一个词
读取操作会自动忽略开头的空白,从一个真正的字符开始读取,直到遇到下一个空白。
#include
#include
using namespace std;
int main()
{
string s;//空字符串
cout << "输入单词,不包含空格" << endl;
while (cin >> s)
{
cout << s << endl;
}
return 0;
}
使用getline一次读入一整行,行的结束标志是回车符(换行符也被读进去了,但是不存入string中)
#include
#include
using namespace std;
int main()
{
string line;//空字符串
cout << "输入单词,可以包含空格" << endl;
while (getline(cin,line))
{
cout << line << endl;
}
return 0;
}
#include
#include
using namespace std;
int main()
{
string s1, s2;//空字符串
cin >> s1 >> s2;
if (s1 == s2)
{
cout << "两个字符串相等" << endl;
}
else {
if (s1 > s2)
cout << "较大的字符串是:" << s1;
else
cout << "较大的字符串是:" << s2;
}
return 0;
}
#include
#include
using namespace std;
int main()
{
string s1, s2;//空字符串
cin >> s1 >> s2;
if (s1.size() == s2.size())
{
cout << "两个字符串等长" << endl;
}
else {
if (s1.size() > s2.size())
cout << "较长的字符串是:" << s1;
else
cout << "较长的字符串是:" << s2;
}
return 0;
}
#include
#include
using namespace std;
int main()
{
string s, s1;//空字符串
while (cin >> s1)
{
s += s1;
}
cout << s << endl;
return 0;
}
死循环,需要输入ctrl+z来结束
可以采用如下的询问方式结束循环:
#include
#include
using namespace std;
int main()
{
char c = 'y';
string s, s1;//空字符串
while (cin >> s1)
{
s += s1;
cout << "是否继续输入(y or n)" << endl;
cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入下一个字符串" << endl;
}
else
break;
}
cout <<"拼接后的字符串:"<< s << endl;
return 0;
}
此时一次只能输入一个字符串,否则第二个字符串的第一个字符会成为c的输入
cout<<" "
,要把空格也接入字符串才能在最后输出有空格字符串 while (cin >> s1)
{
if (!s.size())
s += s1;
else {
s = s + " " + s1;
}
cout << "是否继续输入(y or n)" << endl;
cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入下一个字符串" << endl;
}
else
break;
}
#include
#include
using namespace std;
int main()
{
string s;//空字符串
cin >> s;
cout << "输入的字符是:\t" << s << endl;
for (auto& c : s)
{
c = 'x';
}
cout <<"改变后的字符串:\t"<< s << endl;
return 0;
}
如果处理范围内的每一个元素,采取范围for更好。string可以用下标操作[i]。
使用下标操作前先确定不是空字符串。
#include
#include
using namespace std;
int main()
{
string s;//空字符串
cin >> s;
cout << "输入的字符是:" << s << endl;
for (auto& c : s)
{
if (ispunct(c))//如果该字符是标点符号
{
continue;
}
else {
cout << c << endl;
}
}
return 0;
}
#include
#include
using namespace std;
int main()
{
string s,s1;//空字符串
cin >> s;
cout << "输入的字符是:" << s << endl;
int n = s.size();
for (int i = 0; i < n-1; i++)
{
if (ispunct(s[i]))
{
continue;
}
else {
s1 += s[i];
}
}
cout << "删除标点符号的字符串是:" << s1 << endl;
return 0;
}
const string s = "Keep out!";
for(auto &c : s){/*~*/}
s是一个常量字符串,c的推断类型是常量引用,即c绑定的对象值不能改变。
注意花括号和圆括号的区别
#include
#include
#include
using namespace std;
int main()
{
vector<int> vInt;
int i;
char c = 'y';
while (cin >> i)
{
vInt.push_back(i);
cout << "是否继续输入(y or n)" << endl;
cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入整数" << endl;
}
else
break;
}
for (auto v : vInt)//输出来验证
{
cout << v << " ";
}
cin.clear();
return 0;
}
具体内容采用范围for输出,容量采用size函数即可。
size函数得到的是元素的个数。
#include
#include
#include
using namespace std;
int main()
{
vector<string> vStr;
string s;
char c = 'y';
while (cin >> s)
{
vStr.push_back(s);
for (auto& v : vStr[vStr.size()-1])
{
v = toupper(v);
}
cout << "是否继续输入(y or n)" << endl;
cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入单词" << endl;
}
else
break;
}
for (auto v : vStr)//输出来验证
{
cout << v << endl;
}
cin.clear();
return 0;
}
#include
#include
#include
using namespace std;
int main()
{
vector<int> vInt;
int i;
char c = 'y';
while (std::cin >> i)
{
vInt.push_back(i);
cout << "是否继续输入(y or n)" << endl;
std::cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入单词" << endl;
}
else
break;
}
for (decltype(vInt.size()) i = 0; i < vInt.size() - 1; i++)
{
cout << vInt[i] + vInt[i + 1]<<" ";
}
std::cin.clear();
return 0;
}
#include
#include
#include
using namespace std;
int main()
{
vector<int> vInt;
int i;
char c = 'y';
while (std::cin >> i)
{
vInt.push_back(i);
cout << "是否继续输入(y or n)" << endl;
std::cin >> c;
if (c == 'y' || c == 'Y')
{
cout << "继续输入单词" << endl;
}
else
break;
}
for (decltype(vInt.size()) m = 0; m < vInt.size()/2 ; m++)
{
cout << vInt[m] + vInt[vInt.size()-1-m] << " ";
}
cout << endl;
if (vInt.size() % 2 == 1)//奇数
{
cout << "共有奇数个元素,中间的数字是:" << vInt[(vInt.size()-1) / 2] << endl;
}
return 0;
}
#include
#include
#include
using namespace std;
int main()
{
vector<int> vInt;
srand((unsigned)time(NULL));//生成随机数种子
for (int i = 0; i < 10; i++)
{
vInt.push_back(rand() % 1000);//生成一个1000以内的随机数并添加给vInt
}
auto b = vInt.begin();
auto e = vInt.end();
if (b != e)
{
for (; b != e; ++b)
{
cout << *b << "\t";
*b = 2 * (*b);
}
}
cout << endl;
for (auto a = vInt.begin(); a != vInt.end(); ++a)
{
cout << *a << "\t";
}
cout << endl;
return 0;
}
对于内置类型,定义在所有函数值之外会默认初始化,定义在函数内会导致未定义。
字符数组可以用strlen函数获得字符串的长度。
其他数组必须用sizeof(array) / sizeof(array[0])来获得维度。
a[i] = i 即可
使用标准库函数begin和end
#include
#include
#include
using namespace std;
int main()
{
const int sz = 10;
int a[sz], i = 0;
for (i = 0; i < 10; i++)
{
a[i] = i;
}
int* p = begin(a);//int *p = &a[0], *a
int* e = end(a);
for (auto m = p; m != e; ++m)
{
*m = 0;
}
for (auto n : a)
{
cout << n;
}
cout << endl;
return 0;
}
expression部分是一个用于表示一个序列的对象。
for (auto n : a) { cout << n; }
此处用的是a,和n for (auto v : vStr)
{
cout << v << endl;
}
先比较长度,长度不同一定不同,长度相等则注意比较元素即可。
strlen函数如果对一个不是以空字符作为结束的字符数组使用,将会产生未定义的结果,可能沿着该字符数组的位置一直向前寻找直到遇到空字符。
同样对于指向字符的指针使用while循环,只要指针所指的字符不是空字符,循环就会重复执行,以知在内存中该指针所在的位置之后挨个寻找空字符。
#include
#include
using namespace std;
int main()
{
//对两个C风格字符串进行比较
char str1[80], str2[80];
cout << "请输入两个字符串" << endl;
cin >> str1 >> str2;
//利用cstring头文件定义的strcmp函数比较大小
auto result = strcmp(str1, str2);
switch (result)
{
case 1:
cout << "第一个字符串大于第二个字符串" << endl;
break;
case -1:
cout << "第一个字符串小于第二个字符串" << endl;
break;
case 0:
cout << "第一个字符串等于第二个字符串" << endl;
break;
default:
cout << "未定义的结果" << endl;
break;
}
return 0;
}
C++11 constexpr和const的区别详解
- constexpr 是 C++ 11 标准新添加的关键字,在此之前(C++ 98/03标准)只有 const关键字,其在实际使用中经常会表现出两种不同的语义。
- const int x”只是想强调 x 是一个只读的变量,其本质仍为变量,无法用来初始化 array 容器;
- “constexpr int x”,表明 x 是一个只读变量的同时,x 还是一个值为 5的常量,所以可以用来初始化array 容器。
- C++ 11标准中,为了解决 const 关键字的双重语义问题,保留了 const 表示“只读”的语义,而将“常量”的语义划分给了新添加的 constexpr 关键字。因此 C++11 标准中,建议将 const 和 constexpr 的功能区分开,即凡是表达“只读”语义的场景都使用 const,表达“常量”语义的场景都使用 constexpr。
- “只读”和“不允许被修改”之间并没有必然的联系,如下:
#include
using namespace std;
int main()
{
int a = 10;
const int & con_b = a;
cout << con_b << endl;
a = 20;
cout << con_b << endl;
}
程序执行结果为10 20
- 程序中用 const 修饰了 con_b 变量,表示该变量“只读”,即无法通过变量自身去修改自己的值。但这并不意味着 con_b 的值不能借助其它变量间接改变,通过改变 a 的值就可以使 con_b 的值发生变化。
- 总的来说在 C++ 11 标准中,const 用于为修饰的变量添加“只读”属性;而 constexpr 关键字则用于指明其后是一个常量(或者常量表达式),编译器在编译程序时可以顺带将其结果计算出来,而无需等到程序运行阶段,这样的优化极大地提高了程序的执行效率。
注意C风格字符串用花括号进行列表初始化的时候,如果不手动添加空字符,将不会以空字符结束。采用字符串字面值常量来初始化C风格字符串时则会默认在数组最后添加一个空字符。
#include
#include
using namespace std;
int main()
{
//定义两个字符数组,用字符串字面值初始化
char str1[] = "Welcome to ";
char str2[] = "C++ family!";
const decltype(strlen(str1)) n = 50;
//strlen返回长度时空字符不计算在内
char str[n];//存放前两个数组的连接结果
strcpy(str, str1);//第一个字符串拷贝到结果字符串
strcat(str, str2);//第二个字符串接到结果字符串中
cout << str << endl;
return 0;
}
#include
#include
using namespace std;
int main()
{
//定义两个字符数组,用字符串字面值初始化
char str1[] = "Welcome to ";
char str2[] = "C++ family!";
const decltype(strlen(str1)) n = 50;
//strlen返回长度时空字符不计算在内
char str[n];//存放前两个数组的连接结果
strcpy_s(str, str1);//第一个字符串拷贝到结果字符串
strcat_s(str, str2);//第二个字符串接到结果字符串中
cout << str << endl;
return 0;
}
简单操作:
#include
#include
using namespace std;
int main()
{
//只需要指明要拷贝区域的首元素和尾后元素的地址,即可用数组初始化vector对象
int arr[] = { 0,1,2,3,4,5 };
vector<int> ivec(begin(arr), end(arr));
for (auto v : ivec)
{
cout << v << " ";
}
cout << endl;
return 0;
}
随机数操作:
#include
#include
using namespace std;
int main()
{
//只需要指明要拷贝区域的首元素和尾后元素的地址,即可用数组初始化vector对象
const int sz = 10;
int a[sz];
srand((unsigned) time (NULL));//生成随机数种子
int arr[sz];
for (auto& a : arr)
{
a = rand() % 100;//生成100内的随机数
cout << a << "\t";
}
cout << endl;
vector<int> ivec(begin(arr), end(arr));
for (auto v : ivec)
{
cout << v << "\t";
}
cout << endl;
return 0;
}
#include
#include
using namespace std;
int main()
{
//只需要指明要拷贝区域的首元素和尾后元素的地址,即可用数组初始化vector对象
vector<int> vInt;
srand((unsigned) time (NULL));//生成随机数种子
cout << "vector内的对象是:" << endl;
for (auto& a : vInt)
{
a = rand() % 100;//生成100内的随机数
cout << a << "\t";
}
cout << endl;
int const n = 10;
int a[n];
int* p = a;
for (auto b = vInt.begin(); b != vInt.end(); ++b)
{
*p = *b;
cout << *p << "\t";
p++;
}
cout << endl;
return 0;
}
#include
#include
using namespace std;
int main()
{
//只需要指明要拷贝区域的首元素和尾后元素的地址,即可用数组初始化vector对象
vector<int> vInt;
const int sz = 10;//用于给空vector赋值,以及数组的初始大小
srand((unsigned) time (NULL));//生成随机数种子
cout << "vector内的对象是:" << endl;
for (int i=0;i<sz ; i++)
{
vInt[i] = rand() % 100;//生成100内的随机数
cout << vInt[i] << "\t";
}
cout << endl;
int a[sz];
int* p = a;
for (auto b = vInt.begin(); b != vInt.end(); ++b)
{
*p = *b;
cout << *p << "\t";
p++;
}
cout << endl;
return 0;
}
#include
#include
using namespace std;
int main()
{
//只需要指明要拷贝区域的首元素和尾后元素的地址,即可用数组初始化vector对象
vector<int> vInt;
const int sz = 10;//用于给空vector赋值,以及数组的初始大小
srand((unsigned) time (NULL));//生成随机数种子
cout << "vector内的对象是:" << endl;
for (int i=0;i<sz ; i++)
{
vInt.push_back(rand() % 100);//生成100内的随机数
cout << vInt[i] << "\t";
}
cout << endl;
int a[sz];
int* p = a;
for (auto b = vInt.begin(); b != vInt.end(); ++b)
{
*p = *b;
cout << *p << "\t";
p++;
}
cout << endl;
return 0;
}
使用三个版本的程序输出多维数组ia的元素,且直接写出数据类型:
for(auto& row:ia)
{
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
int (&row)[4] = ia[1];
for(auto (&row)[4]:ia)
{
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
cout << "利用普通for和下标运算符" << endl;
for (int i = 0; i != 3; i++)
{
for (int j = 0; j != 4; j++)
{
cout << ia[i][j] << " ";
}
cout << endl;
}
int *p[4] = ia
会变成整型指针的数组 int ia[3][4];
int (*p)[4] = ia;//p指向含有4个整数的数组
p = &ia[2];//p指向ia的尾元素
其使用方法如下:
for (int (*p)[4] = ia; p != ia + 3; p++)
{
for (int* q = *p; q != *p + 4; q++)
{
cout << *q << " ";
}
cout << endl;
}
return 0;
for(auto p = ia; p != ia+3; ++p)
{
for(auto q = *p; q != *p+4; ++q)
{
cout << *q << "" ;
}
cout << endl;
}
for(auto p = begin(ia); p != end(ia); ++p)
{
for(auto q = begin(*p); q != end(*p); ++q)
{
cout << *q << "" ;
}
cout << endl;
}
最后的总程序如下所示:
#include
using namespace std;
int main()
{
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "利用范围for" << endl;
for(int (&row)[4]:ia)
{
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
cout << "利用普通for和下标运算符" << endl;
for (int i = 0; i != 3; i++)
{
for (int j = 0; j != 4; j++)
{
cout << ia[i][j] << " ";
}
cout << endl;
}
cout << "利用普通for和指针:" << endl;
for (int (*p)[4] = ia; p != ia + 3; p++)
{
for (int* q = *p; q != *p + 4; q++)
{
cout << *q << " ";
}
cout << endl;
}
return 0;
}
#include
using namespace std;
using int_array = int[4];
//typedef int int_array[4];
int main()
{
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "利用范围for" << endl;
for(int_array &row:ia)//auto (&row)[4]
{
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
cout << "利用普通for和下标运算符" << endl;
for (int i = 0; i != 3; i++)
{
for (int j = 0; j != 4; j++)
{
cout << ia[i][j] << " ";
}
cout << endl;
}
cout << "利用普通for和指针:" << endl;
for (int_array *p = ia; p != ia + 3; p++)//int (*p)[4] = ia
{
for (int* q = *p; q != *p + 4; q++)
{
cout << *q << " ";
}
cout << endl;
}
return 0;
}
注意for (int* q = *p; q != *p + 4; q++)
变成了for (auto q = *p; q != *p + 4; q++)
使用了auto就不用在自行指定指针类型了
#include
using namespace std;
int main()
{
int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
cout << "利用范围for" << endl;
for(auto (&row)[4]:ia)
{
for (auto col : row) {
cout << col << " ";
}
cout << endl;
}
cout << "利用普通for和下标运算符" << endl;
for (auto i = 0; i != 3; i++)
{
for (int j = 0; j != 4; j++)
{
cout << ia[i][j] << " ";
}
cout << endl;
}
cout << "利用普通for和指针:" << endl;
for (auto (*p)[4] = ia; p != ia + 3; p++)
{
for (auto q = *p; q != *p + 4; q++)
{
cout << *q << " ";
}
cout << endl;
}
return 0;
}
(C++Primer 2.4.4)
const int max = 20;//max是常量表达式
const int limit = max + 1;//limit是常量表达式
int size = 27;//size不是常量表达式
const int sz = getsize();//不是常量表达式
尽管sz本身是一个常量,但是具体值直到运行的时候才可以获取到
constexpr int max = 20;//20是常量表达式
constexpr int limit = max + 1;//max+1是常量表达式
constexpr int sz = getsize();
//只有当getsize是一个constexpr函数的时候这个语句才正确
constexpr int sz = getsize();
,geisize不是constexpr函数,编译器会报错
- constexpr函数:是指能用于常量表达式的函数。
- 定义constexpr函数与其他函数类似,但是有几项约定:函数返回类型和所有形参类型都是字面值类型;函数体中必须有且只有一条return语句。
- 为了在编译过程中随时展开,constexpr函数被隐式地指定为了内联函数。
- constexpr函数不一定返回常量表达式。
const int* p = nullptr;//p是一个指向整型常量的指针
constexpr int* q = nullptr;//q是一个指向整数的常量指针
int j = 0;
const int i = 42;//i的类型是整型常量
constexpr const int *p = &i;//p是常量指针,指向整型的常量i
constexpr int *q = j;//q是常量指针,指向整数j