#include<iostream>
#include<string>
#include<vector>
#include<cctype>
#include<initializer_list>
#include<istream>
#include<fstream>
//run时候的问题我觉得是因为把这个import到了3文件
using std::istream;
using std::ostream;
using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::getline;
using std::size;
using std::empty;
using std::vector;
using std::begin;
using std::end;
using std::initializer_list;
typedef string::size_type sz;
using F = int(int*, int);//F是函数类型
using PF = int(*)(int*, int);//PF是指针类型
string screen(sz ht = 24, sz wid = 80, char backgrnd = ' ');
string screen1(sz sd=12 , sz ed=78, char=' ');
bool lengthcompare(const string &, const string &);//用来函数指针
//声明放在调用后面的函数
int fact(int cc);
void reset(int *p);
void re(int &i);
void print(const int *beg, const int *end);
void printtt(const int ia[10]);
const string &shortS(const string &s1, const string &s2);
string &shortSt(string &s1, string &s2);
char &get_val(string &str, string::size_type ix);
int main() {
cout << "enter two numbers,please" << endl;
int v1, v2;
cin >> v1 >> v2;
cout << "the sum of " << v1 << "and " << v2 << "is " << v1 + v2 << endl;//输入输出
string s;
while (getline(cin,s))//getline函数
if(s.size()>3)
cout << s << endl;
string ass = "sad ";
string fd = ass + ", ";
string ed = ", ";
string gd = ed + ", ";//不允许字符串字面值直接相加
string v("sdsafa asdfasw ew");
for (auto c : v)
cout << c << endl;//按字符输出
string ds = "hello world!!!@";
decltype(ds.size()) punct_cnt = 0;
for (auto c : ds)
if (ispunct(c))
++punct_cnt;
cout << punct_cnt << "\n" << ds << endl;
string rd("dsfa ef!!");
for (auto &c : rd)
c = toupper(c);
cout << rd << endl;//重新试的时候忘了include string了 没问题
//这个例子实在说明使用引用可以改变我们的实参值
const string sixteen ("0123456789ABCDEF");
cout << "enter a series of numbers" << endl;
string result;
string::size_type n;
while (cin >> n)
if (n < sixteen.size())
result += sixteen[n];
cout << result << endl;
string es("sde efrf");
for (auto &c : es)
if(!es.empty())
c = 'x';
cout << es << endl;
vector <string>art = { "ss" , "ds","df"};//列表初始化
vector<string>aw(art);//直接传递拷贝初始化
vector<int>qwer(12, -2);//创建指定数量元素 以上为三种直接初始化的例子 元素较少,元素全相同,一个是另一个的副本
vector<int>eddc(12, 3);
vector<string>ws(12, "dew");
vector<string>ed(12);//int和string支持默认初始化 有些未必支持
vector<int>wws{ 10,1 };//列表初始化
vector<int>wse(10, 1);//10个1
vector<int>was(10);//10个初始值为0
vector<int>wqw{ 10 };//1个初始值为0
vector<string>qwe{ 10,"ws" };
int ww;
vector<int>tr;
while (cin>>ww)
{
tr.push_back(ww);
}//添加元素类似Python的append后入
vector<string>wx{ "wdew","ws","wsc" };
for (auto i : wx)
cout << i << " ";//千万注意,这是vector,不能直接cout,以下边cout可以的
vector<unsigned>score(11, 0);
unsigned grade;
while (cin >> grade)
{
if (grade <= 100)
++score[grade / 10];
}
vector<int>we;
we.push_back(10);
int sad = fact(4);
cout << sad << endl;
int i = 42;
reset(&i);
cout << i << endl;//引用还是改变了实参值
int j = 42;
re(j);
cout << j << endl;//传引用 改变实参值
int j[2] = {0,1};
print(begin(j), end(j));//使用的标准库函数
int j[10] = { 0,1,2,3,4,8,21,12,23,};//你把初始值设定多了会报错 但少了不会报错
printtt(j); //????
string aa = shortS("dsfs", "dsdaewde");
cout << aa << endl;
//shortSt("as", "wedecee") = "zzzzzzzzzz";这一行错在他本身就是个常量,不是个可以接纳赋值的变量
string suv("a value");
cout << suv << endl;
get_val(suv, 0) = 'A';//你看它函数定义 它的返回值类型是引用 所以可以改变
cout << suv << endl;
screen(66);//形参不能跳过设定,必须一一设定,或者从前往后
//函数指针的应用
bool(*pf)(const string&, const string &);//你看,先在下面定义函数,然后在前面声明一下下,接着在这里定义一个函数指针(尚未初始化)
pf = lengthcompare;//这是赋值哦很简单
bool b1 = pf("hello ", "sadew");//这里是函数指针的调用
bool b2 = (*pf)("sd", "ewdfew");//一样样的跟上头
bool b3 = lengthcompare("wde", "wedf");//等价
Sales_data total;
//返回一个this类型的函数
Screen::pos ht = 24, wd = 80;
Screen scr(ht, wd, ' ');//定义初始化一个Screen类
Screen *p = &scr;//类对象的使用
char c = scr.get();
c = p->get();
string rf = screen1(23, 34);//这是调用有部分默认形参的函数
double r;
r = account::rate();//这是访问account类的static成员rate
account ac1;
account *ac2 = &ac1;
r = ac1.rate();//虽然static成员不属于任何一个account类的对象 但可以通过对象访问(引用 指针等)
r = ac2->rate();
auto old_state = cin.rdstate();//
cin.clear();
cin.setstate(old_state);
system("pause");return 0;
}
int fact(int cc) {
int co = 1;
while (cc>1)
{
co *= cc--;
}
return co;//调用函数普通 2.如果有两个形参 也得把两个都写出类型如int a,int b
}
void reset(int *p) {
*p = 0;//只改变了&i实参的i值
p = 0;//指针形参,传值参数,不会改变实参值
}
void re(int &i)//传引用参数,可以改变实参的值
{
i = 0;
}
void print(const int *beg, const int *end) {
while (beg!=end)
{
cout << *beg++ << endl;//这种方法规定实参的首末指针(使用标准库规范begin,end)
}
}
void printt(const int ia[], size_t size) {//直接规定了指针和实参的长度size
for (size_t i = 0; i != size; ++i) {
cout << ia[i] << endl;
}
}
void printtt(const int ia[10]) {//无措但是该函数遇到调用时数组并非10个时也工作因此可能导致输出多个0
for (size_t i = 0; i != 10; ++i) {
cout << ia[i] << endl;
}
}
void error_msg(initializer_list<string> i1) {//initializer_list的应用 可以接受不同数量的形参
for (auto beg = i1.begin(); beg != i1.end(); ++beg) {
cout << *beg << " ";
cout << endl;
}
}
void swap(int &a, int &b) {//函数中return执行条件中途退出的功能类似于break
if (a == b)
return;
else
{
int temp = a;
a = b;
b = temp;
}
}
const string &shortS(const string &s1, const string &s2) {//形参尽量避免拷贝,尽量使用引用,第二,return语句
return s1.size() <= s2.size() ? s1 : s2;
}
string &shortSt(string &s1, string &s2) {//尝试
return s1.size() <= s2.size() ? s1 : s2;
}
char &get_val(string &str, string::size_type ix) {//返回值是引用类型 所以可以改变 也就是相当于赋值
return str[ix];
}
int mul(int val) {//递归函数
if (val > 1)
return mul(val - 1)*val;
return 1;
}
void print(int &a, string &b) {//同名函数形参不一样即可 重载
cout << a << " " << b << endl;
}
typedef string::size_type sz;
string screen(sz , sz , char ) {//默认形参
return 0;
}
inline string screen1(sz, sz, char) {//部分默认形参形式 内联函数
}
constexpr int cd = 23;
constexpr int new_pr() { return 42; }
constexpr int foo = new_pr();//可以用于常量表达式的函数 才叫做常量表达式函数constexpr
void f(int) {
}
void f(int, int) {
}
void f(double t, double tz) {//函数匹配问题
}
//函数指针可以做形参 也可以做函数返回值
bool lengthcompare(const string &, const string &) { return 0; }//用来函数指针
void usebigger(const string &s1, const string &s2, bool pf(const string &, const string &)) {}//这是函数(指针)作为形参的第一次pf会被转为指针
void usebiggerr(const string &s1, const string &s2, bool *pf(const string &, const string &)) {}//等价
//函数的返回值为 指向函数的指针
PF f1(int){}//该函数返回指向函数的指针 在前面先声明using哦——函数指针作为另一函数的返回值
F *f2(int){}//显式地指定返回类型是指向函数的指针
//类
struct Sales_data//一个类的实验
{//这是进阶版的四个函数
public://这两个叫做访问说明符 public允许在整个程序访问
Sales_data() = default;//三个定义的构造函数 default是使之指向默认构造
Sales_data(const string &s):bookNo(s){}//:表示对数据成员赋初值,成为初始值列表 所以函数体为空
Sales_data(const string &s,unsigned n,double p)://所有定义在类内部的函数自动是inline滴
bookNo(s),units_sold(n),revenue(p*n){}
Sales_data(istream &);//这个是声明的构造函数 定义在类外部
//下面(这是初阶版的)
string isdn()const { return bookNo; }//直接定义函数
Sales_data& combine(const Sales_data&);
double avg_price()const;//单纯声明
private://而private只允许被类的成员函数调用访问(封装在内部啦)danshi这样的话辅助函数add和print也没法访问了 然后看有缘friend
string bookNo;//成员定义放在前后没有任何关系(编译原理)
unsigned units_sold = 0;
double revenue = 0.0;
friend Sales_data add(const Sales_data&, const Sales_data&);//有缘friend用来允许辅助函数add等对private的成员数据进行访问
friend istream &read(istream&, Sales_data&);//friend不能代替函数调用的声明 只是对访问数据的声明耳
friend ostream &print(ostream&, const Sales_data&);//friend只可以出现在类定义内部,但次序随意
};
Sales_data add(const Sales_data&, const Sales_data&);//???XDD这些三个都是类的辅助函数不属于类本身 在外
ostream &print(ostream &, const Sales_data&);//辅助函数de 声明XD
istream &read(istream&, Sales_data&);
double Sales_data::avg_price()const {//在类的外部定义成员函数 注意1.声明类的名字2.如果是常量成员函数就const3.类内成员编译可直接识别
if (units_sold)return revenue / units_sold;
else
return 0;
}
istream &read(istream &is, Sales_data &item) {//以下三个是对于类的辅助函数的定义
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item) {
os << item.isdn() << " " << item.units_sold << " " <<
item.revenue << " " << item.avg_price();
return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs) {
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Sales_data::Sales_data(istream &is) { read(is, *this); }//这是构造函数在类外部 函数体非空(执行一定的功能)
class Screen {
public:
friend class window_mgr;//声明友元类
//也可以直接去把需要调用别人数据的成员函数声明为有缘 但是对重载的函数需要一一声明
//友元函数甚至可以直接定义在调用的这个的类内部,但是 友元声明终究不是函数声明,它只代表访问权限 要用该函数还是要声明 ok??
typedef string::size_type pos;
Screen() = default;//默认
Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c){}//定义在类内的成员函数自动inline 这行是非默认初始化
char get()const { return contents[cursor]; }
inline char get(pos ht, pos wd)const;//这个是在类外定义的成员函数但在类内直接显式的声明称inline哒
Screen &move(pos r, pos c);
//小进阶
Screen &set(char);//注意了 我们定义的这个函数就是个引用型& 如果不是将无法*this来改变Screen的值
Screen &set(pos, pos, char);//定义在外面
Screen &display(ostream &os) { do_display(os); return *this; }//这两个display函数涉及重载 所以在某个对象上调用之
const Screen &display(ostream &os)const { do_display(os); return *this; }//时该对象是否const决定了调用which
private:
pos cursor = 0;
pos height = 0, width = 0;
string contents;
void do_display(ostream &os) const { os << contents; }//负责打印screen 的工作内容
};//class后有;记得要
inline //类外的成员函数想要inline必须手动inline哦
Screen &Screen::move(pos r, pos c) {
pos row = r * width;
cursor = row + c;
return *this;
}
char Screen::get(pos r, pos c)const {//已经在类内声明为inline辣
pos row = r * width;
return contents[row + c];
}
class screen {//定义一个const的成员函数和一个即将被调用的mutable数据,他是可变的
public:
void some_member() const ;
private:
mutable size_t access_ctr;
};
void screen::some_member()const {
++access_ctr;
}
class window_mgr {//类数据成员的初始化{}或者=
public:
using ScreenIndex = vector<Screen>::size_type;
void clear(ScreenIndex);
private:
vector<Screen>screens{ Screen(24,80,' ') };
};
void window_mgr::clear(ScreenIndex i) {//作为有缘类的成员函数来调用朋友的数据height,width
Screen &s = screens[i];
s.contents = string(s.height*s.width, ' ');
}
inline Screen &Screen::set(char c) {
contents[cursor] = c;//设置当前光标所在位置的新值??
return *this;
}
inline Screen &Screen::set(pos r, pos col, char ch) {
contents[r*width + col] = ch;
return *this;
}
class student;//类可以先声明不定义
Sales_data aa;
struct Sales_data as;//同上等价
//student ads;
class link_screen {
Screen window;
link_screen *next;
link_screen &asd;//在这个类中,类还没被定义完 这时可以包含自身类型的引用或指针,而不能直接用它定义类
};
class X {
int i;
int j;
private:
X(int val):j(val),i(j){}
};//因为成员初始化顺序需要和类定义中的出现顺序一致 所以应该先i后j 但编译没警告
class account {
public:
void calculate() { amount += amount * interestRate; }//成员函数可以直接访问static成员
static double rate() { return interestRate; }//静态成员不得const也不得调用this
static void rate(double);//使用作用域运算符可访问 她的定义在外
private:
string owner;
double amount;
static double interestRate;//
static double initRate();
};
void account::rate(double newrate) {//在类外定义static成员函数
interestRate = newrate;//ta在类里是个static,但不能重复说static
}
double account::interestRate = initRate();//必须在类的外部定义和初始化每个static成员,只许定义once
C++_programming_basis_1(函数,类,指针,const)
最新推荐文章于 2022-05-18 16:43:08 发布