形式为: using namespace::name ;
如
using std::cout;using std::cin;using std::endl;
需要注意的是头文件中不应该有using 声明。
string 表示可变长的序列,使用string必须首先包含string头文件。
#include ;using std::string;
#include
#include
using namespace std;
int main() {
string s1,s;
cin >> s1;
cout << s1 << endl;
getline(cin, s);
cout << s << endl;
if (getline(cin,s)) {
if(s.empty()){
cout << "s is empty" << endl;
}
else {
cout << "the size of s is : " << s.size() << endl;
for (int i = 0; i < s.size(); s, i++) {
cout << "s[" << i << "]= " << s[i] << endl;
}
}}
cout << s1 + s << endl;
if (s1 == s) {
cout << "s1=s" << endl;
}
else {
s1 = s;
}
cout << s1 << "===" << s << endl;
return 0;
}
在cctype头文件中定义了以下一组标准库函数:
利用for语句遍历给定序列的每个元素:
for(declaration:expression)
statement
如
string str("some string");
for(auto c:str)
cout<<c<<endl;
如下面代码定义了一个统计一段字符串中的各种字符类型的出现次数
#include
#include
using namespace std;
void readstr(string str) {
if (!str.empty()) {
int alpha = 0, cntrl = 0, digit = 0, graph = 0, lower = 0, upper = 0, print = 0, punct = 0, space = 0;
//字母,控制字符,数字,不是空格可打印,小写字母,大写字母,可打印,标点符号,空白
for (auto c : str) {
if(isprint(c)){
print++;
if(isgraph){
graph++;
if (isalpha(c)) {
alpha++;
if (islower(c))
lower++;
else
upper++;
}
if (isdigit(c))
digit++;
if (ispunct(c))
punct++;
}
}
if (isspace(c))
space++;
}
cout << "字母:"<< alpha<< ",控制字符:" <<cntrl<< " ,数字:" <<digit<< ",不是空格可打印:" <<graph
<< ",小写字母:" <<lower<< ",大写字母:"<<upper << ",可打印:" <<print<< ",标点符号:" <<punct<< ",空白:"<<space << endl;
}
}
int main() {
string s1("aaaaAAA1231234sdfgw3sa,sd,d,d,f,,f,s ...asa..\n\t\d\s\a\\\S\ASD\DAFXCVZ\PSFSF;;D`` sddfasfxvf");
readstr(s1);
//s1 = "aaa";
for (auto &str : s1) {
str=toupper(str);
}
cout << s1 << endl;
return 0;
}
结果为
字母:53,控制字符:0 ,数字:8,不是空格可打印:81,小写字母:33,大写字母:20,可打印:81,标点符号:17,空白:7
AAAAAAA1231234SDFGW3SA,SD,D,D,F,,F,S ...ASA..
DS\SASDDAFXCVZPSFSF;;D`` SDDFASFXVF
vector表示对象的集合,其中的所有对象的类型都相同。使用vector必须包含对应的头文件。vector是一个类模块。模板本身不是类或函数,相反可以将模板作为编译器生成类或函数的一份说明。编译器根据模板生成类或函数的过程称为实例化(instantiantion)。使用模板时应指出编译器应把类或函数实例化为何种类型。
对于vector,需要给定vector内存放的对象的类型,如
vector<int> ivec;
vector<Sales_item> sales;
vector<vector<string>>file;
vector能容纳大多数类型的对象作为其元素。
利用vector的成员函数push_back,把一个值push到vector对象的尾端。
vector<int> vi;
for(int i=0;i!=100;i++)
vi.push_back(i);
除了使用下标运算符来访问string对象的字符或vector对象的元素,还可以使用迭代器。
迭代器的类型拥有begin和end成员,begin成员负责返回指向第一个元素的迭代器。end成员负责返回指向容器“尾元素的下一个位置(one past the end)”的迭代器。
迭代器运算符:
如下我们对比用指针和用迭代器来遍历string和vector,相比较可以看出二者虽然方式不同但其实是很相似的,但迭代器用起来更方便一些。
#include
#include
#include
using namespace std;
int main() {
string s{ "asdfasdf" };
vector<int> a{ 1,2,3,2,231,2,2,1,3 };
for (char* p = &s[0]; p!=&s[s.size()-1]; p++) {
cout << *p << endl;
}
for (int* pi = &a[0]; pi != &a[a.size() - 1]; pi++) {
cout << *pi << endl;
}
for (auto str = s.begin(); str != s.end(); str++) {
cout << *str << endl;
}
for (auto cc = a.begin(); cc != a.end(); cc++) {
cout << *cc << endl;
}
return 0;
}
(注意迭代器大多数没有定义<运算符,但基本都定义了==和!=运算符,所以我们要养成用!=的习惯。
一般来说我们不需要知道迭代器的类型是什么,实际上标准库类型使用iterator和const_iterator来表示迭代器的类型。
vector<int>::iterator it;
string::iterator its;
vector<int>::const_iterator cit;
string::const_iterator cits;
const_iterator和常量指针差不多。
注意解引用和访问成员操作时:
(*it).empty();//必须要加括号
为了简化操作,我们这时可以用箭头运算符(->)
it->empty();
数组与vector非常像,但数组的大小时不可变得,也就不能随意的向数组添加元素。
unsigned cnt=42;
constexpr unsigned sz=42;
int arr[10];
int *parr[sz];
string bad[cnt];//错误,cnt不是常量表达式
string strs[get_size()];//get_size是constexpr时正确,否则错误
const unsigned ssz=3;
int ia1[ssz]={0,1,2};
int a2[]={0,1,2};
int a3[5]={0,1,2}; //<=>int a3[]={0,1,2,0,0};
sring a4[3]={"hi","bye"};
int a5[2]={0,1,2}; //错误
//字符数组的特殊性
char a1[]={'c','+','+'}; //列表初始化,无空字符
char a2[]={'c','+','+','\0'}; //显示添加空字符
char a3[]="c++"; //自动添加表示字符串结束的空字符
consr char a4[6]="Daniel"; //错误,没有空间存放空字符
//不允许拷贝和赋值
int a[]={0,1,2};
int b[]=a; //错误
b=a; //错误
//复杂的声明
int *ptrs[10]; //ptrs是一个具有10个整型指针的数组
int (*parray)[10]=&arr;//parray指向一个含10个整数的数组
int (&arrRef)[10]=arr;//arrRef引用一个含有10
int *(&arrr(10))=ptrs; //arrr是一个含有10个指针的引用
注意不存在引用的数组。
#include
#include
#include
using namespace std;
int main() {
int a[10];
int(*pa)[10] = &a;
int(&af)[10] = a;
for (int i = 0; i != size(a); i++) {
//(*pa)[i] = i;
af[i] = i;
}
for (auto c : a)
cout << c << endl;
return 0;
}
使用数组下标时通常将其定义为size_t类型。size_t是一种与机器无关的无符号类型。在cstddef中定义了size_t类型,这个文件是c标准库stddef.h头文件的c++版本。
数组有一个特性:在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首个元素的指针
string nums[]={"one","two","three"};
string *p=&nums[0];
string *p1=nums;
int ia[]={0,1,2,3,4,5,5,6,7,8,9};
auto ia2(ia);//ia2是一个指向ia第一个元素的指针,等价于 auto ia2(&ia[0]), 类型为 int *
decltype(ia)ia3={0,1,2,3,4,5,6,7,8,9};
但decltype(ia)返回的类型是10个整数的数组。
数组也能使用迭代器,相关的操作也都支持,但用法有所不同。
int ia[]={0,1,2,3,4,5,5,6,7,8,9};
int *beg=begin(ia);
int *last=end(ia);
auto n=begin(ia)-end(ia);
两个指针相减的结果的类型是一种名为ptrdiff_t的标准库类型,是带符号的。
c风格字符串是一种约定俗成的写法。c语言标准库提供一组函数来操作c分隔字符串,他们定义在cstring头文件中,cstring是c语言头文件string.h的c++版本。
严格地说c++中没有多维数组,通常所谓的多维数组时数组的数组。
for语句来处理多维数组
for(const auto &row:ia)
for(auto col:row){
cout<<col<<endl;
}
用指针遍历二维数组时可能有点绕,一定要理清楚一些概念(指针指向的是数组还是数组中的元素)
#include
#include
#include
using namespace std;
int main() {
int a[10][10];
int o = 0;
for (int(*p)[size(a)] = a; p != a+size(a); p++)
for (int* pp = *p; pp != *p+size(*p); pp++)
*pp = o++;
for (const auto& c : a)
for (auto cc : c)
cout << cc << endl;
return 0;
}
或者可以用auto来进行简写,但最好明白不用auto怎么写,要理解到位
#include
#include
#include
using namespace std;
int main() {
int a[10][10];
int o = 0;
for (auto p=a;p!=a+size(a); p++)
for (auto pp=*p;pp!=*p+size(*p); pp++)
*pp = o++;
for (const auto& c : a)
for (auto cc : c)
cout << cc << endl;
return 0;
}