7月_C++_1

 

1.

#include <iostream>

#include <climits>

//climits包含整型的限制信息,INT_MAX为int的最大取值,CHAR_BIT为字节的位数

using namespace std;

int main()

{

int n_int = INT_MAX;

short n_short = SHRT_MAX;

long n_long = LONG_MAX;

//sizeof操作符返回类型或变量的长度,单位为字节

//不同的系统,值可能不同

cout<<"int is " << sizeof(int) <<"bytes."<<endl;

cout<<"int is " << sizeof(n_int) <<"bytes."<<endl;

cout<<"short is " << sizeof(n_short) <<"bytes."<<endl;

cout<<"short is " << sizeof(short) <<"bytes."<<endl;

cout<<"long is " << sizeof(n_long) <<"bytes."<<endl<<endl;

 

 

//具体的值

cout<<"big int is " << n_int <<endl;

//int,4字节,32bits,2的32次方为42,9496,7296;除以2:带负号为最小值-21 4748 3648;减1,为最大值21 4748 3647

cout<<"short is " << n_short <<endl;

cout<<"long is " << n_long <<endl;

cout<<"small int is " << INT_MIN <<endl;

cout<<"bits per byte is " << CHAR_BIT <<endl;

return 0;

}

 

092717_fNau_3244697.png

 

2.//超越限制,将从范围另一端取值

#include <iostream>

#include <climits>

#define num 0 //将所有num替换为0

using namespace std;

int main()

{

short sam = SHRT_MAX;//sam = 32767

unsigned short sue = sam;//sue的最大值为65535,0 ~ 65535

sam = sam + 1;

sue = sue + 1;

cout<<"32767加1后,sam="<<sam<<endl;

//sam已是最大值,加1,变为-32768;超越限制,将从范围另一端取值

cout<<"32767加1后,sue="<<sue<<endl;//sue=32768

sam = num;

sue = num;

sam = sam - 1;

sue = sue -1;

cout<<"0-1,sam="<<sam<<endl;//sam=-1

cout<<"0-1,sue="<<sue<<endl;//sue=65535,超越限制,将从范围另一端取值

return 0;

}

092747_ga28_3244697.png

3.//默认情况,cout以10进制显示数

#include <iostream>

using namespace std;

int main()

{

int a = 45;

int b = 045; //以0开头,8进制

int c = 0x45; //以0X或0x开头,16进制

cout<<"a="<<a<<"\n"<<"b="<<b<<"\n"<<"c="<<c<<"\n";

return 0;

}

8进制的045转10进制:4*8+5=37

092834_Y9L7_3244697.png

4.//显示本来的面目

#include <iostream>

using namespace std;

int main()

{

int a = 45;

int b = 42;

int c = 45;

cout<<"a="<<a<<endl;

cout<<hex; //此时,显示以16进制显示

cout<<"b="<<b<<endl;

cout<<oct; //此时,显示以8进制显示

cout<<"c="<<c<<endl;

return 0;

}

092909_hrCL_3244697.png

 

5./*成员函数cout.put(),用来输出一个字符

iostream是类,类定义了如何表示和控制数据,对象使用这些定义实现;成员函数归类所有,描述操纵数据的方法。

只能通过类的特定对象(这里是cout)使用成员函数;

. , 成员操作符

cout.put(),通过类对象cout使用函数put()

*/

#include <iostream>

int main()

{

using namespace std;

char ch = 'M'; //M的编码是77,此时,ch中存的是77

int i = ch;

cout<<"the ascii code for "<< ch <<" is "<<i<<endl;

//77是存储在ch中的值,内存中存储的是77

//输入时,cin将M转换为77;输出时,cout将77转换为M

 

ch = ch+1; //ch = 'N'

i = ch; //i=78

cout<<"the ascii code for "<< ch <<" is "<<i<<endl;

cout<<"using cout.put(ch)=";

cout.put(ch);//cout.put()只能另起一行使用

cout.put('!');//cout.put()代替了<<,感觉实际没啥卵用。

cout<<endl;

return 0;

}

 

092929_lQsz_3244697.png

 

092943_0lB1_3244697.png

 

\v在vc6中,显示一个符号。

\r不知道显示的啥意思。

 

6.#include <iostream>

int main()

{

using namespace std;

//cout.setf(ios_base::fixed,ios_base::floatfield);

float a = 3.456786436; //没有上面那一行,a取前6位,第7位是6,四舍五入,a=3.45679;若第7位是3,不进行四舍五入

float b = 6.7E6;

cout<<"a="<<a<<"\nb="<<b<<endl;

return 0;

}

 

093018_2pb4_3244697.png

 

093039_5Pyr_3244697.png

//从小数到int的转换,不进行4舍5入

7.

093154_3BHp_3244697.png

 

8.

093211_g0FK_3244697.png

字符数组,遇到空格‘\0’,就停止输入。所以name2【3】=‘\0’,就只输出name2的0,1,2这3个元素。

9.

//输入的隐藏致命点!

#include <iostream>

#include<cstring>

int main()

{

using namespace std;

const int Size = 11;

char name1[Size],name2[Size];

cout<<"输入name1:\n";

cin>>name1;

cout<<"输入name2:\n";

cin>>name2;

//还没等输入name2,就跳过去了。

cout<<"nishi\n";

cout<<name1<<endl<<name2<<endl;

return 0;

}

 

093234_Ewly_3244697.png

cin.getline(name1,10),10代表name1的大小,一般要和name[size]的size一致。

再输入qwe rty,就不会分别写入name1和name2中,而是直接都写到name1中。

 

2017.7.6

1.两种确定的字符串中的字符数:

int len1 = str1.size(); //str1只能是string!

int len2 = strlen(str1); //str1只能是字符数组!

#include <iostream>

#include <string>

#include <cstring>

 

int main ()

{

using namespace std;

char str1[20];

string str2;

cout<<strlen(str1)<<endl;

//未初始化的数组,得到的大小可能比20大。

cout<<str2.size()<<endl;

cout<<"输入str1:\n";

cin.getline(str1,20);

cout<<str1<<endl;

getline(cin,str2); //注意:getline之前没有cin! 输入string,遇到回车有停止键

cout<<"2345\n";

cout<<str2<<endl;

cin>>str2; //cin,遇到空格就停止输入,遇到回车不停止

cout<<str2<<endl;

return 0;

}

093257_bWWj_3244697.png

cin.getline(str1,20),函数getline()是类istream的一个类方法,cin是istream的一个对象。

getline(cin,str)不是类方法,cin告诉从哪里获取输入,str为字符串名,不需要指定大小,自动调整大小。

 

2.结构,可以存储多种不同类型的数据。如球员的身高,体重,工资,姓名。

创建结构,先定义结构描述,他描述标记能存储的数据类型,然后按描述创建结构变量。

例:

struct qiu

{

char name[20]; //结构成员

float tall; //结构成员

int age; //结构成员

};

关键字struct表明,代码定义结构的布局。qiu是结构的名称,qiu是新类型的名称,且qiu有3个结构成员。

 

创建qiu这一类型的变量:

qiu hat; //和int a 没啥区别。

struct qiu could; //C++允许声明结构变量时省略struct。

hat的类型为qiu,可用 .(成员操作符) 访问各个成员。

hat.name,指name成员,name是char类型,所以hat.name也是char型。

注意,hat是一个结构!

 

3.fibonacci sequence

/*

fibonacci sequence

*/

#include <iostream>

int main ()

{

using namespace std;

int f1=1,f2=1,t,a; //t,临时变量;a,要求的第几个数

cout<<"enter num a:\n";

cin>>a;

cout<<"f1="<<f1<<" f2="<<f2<<endl;

for(int i=3;i<=a;i++){

t = f2;

f2 = f1+f2;

f1 = t;

cout<<"第 "<<i<<"个数是"<<f2<<endl;

}

return 0;

}

093316_VYBt_3244697.png

 

/*

fibonacci sequence

一次输出2个数

*/

#include <iostream>

int main ()

{

using namespace std;

int f1=1,f2=1,t,a; //t,临时变量;a,要求的第a组数,每组2个数

cout<<"enter num a:\n";

cin>>a;

cout<<"f1="<<f1<<" f2="<<f2<<endl;

for(int i=2;i<=a;i++){

f1 = f1+f2;

f2 = f1+f2;

cout<<"第 "<<(2*i-1)<<"个数是"<<f1<<endl;

cout<<"第 "<<(2*i)<<"个数是"<<f2<<endl;

}

return 0;

}

093333_T6rL_3244697.png

 

 

 

7.struct,结构体

#include <iostream>

#include <string>

/*用string本来是想在struct man中定义string name;结果沙比的vc6.0编译器不让通过,只能用char name【20】了

C++ primer plus第五版说的很清楚,Microsoft Visual C++7.0之前的版本都不能:在结构体中对以string对象作为作为成员的结构进行初始化。

using namespace std;

 

//定义结构

struct man

{

char name[20];

//各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。

float height;

int age;

} wang,lang; //可以在定义结构后面直接声明变量

 

int main()

{

man wang = {"wang fei",1.6,29}; //用逗号分隔,初始化结构

man liu = //定义变量

{

"liu huo",

1.8,

24

};

lang = wang; //变量间可直接赋值

cout<<"wang:"<<wang.age<<" "<<wang.height<<" "<<wang.name<<endl;

cout<<"lang:"<<lang.age<<" "<<lang.height<<" "<<lang.name<<endl;

cout<<"liu:"<<liu.name<<endl;

cout<<"liu:"<<liu.height<<endl;

cout<<"liu:"<<liu.age<<endl;

return 0;

}

093416_Jt5n_3244697.png

警告:warning C4305: 'initializing' : truncation from 'const double' to 'float'

初始化时,截断 从常量double到float

原因:在c++里,默认的小数类型是double,出现const是因为1.6和1.8是一个常数。由于编译器会将浮点常量默认地看作double,所以将会出现截断的警告。   

为了避免警告,你可以将这个常量显式声明为float常量:   

float a=4.14E-3f;

float a=3.1f;

所以在1.6或者1.8后加一个 f 即可

 

8.

//结构数组

#include <iostream>

using namespace std;

 

//定义结构

struct man

{

char name[20];

//各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。

float height;

int age;

} ;

int main()

{

man woman[3] =

{ //woman首先是一个数组,类型是man,总的来说就是包含3个man结构的数组

{"liu",1.61f,20},

{"wang",1.65f,21},

{"diwu",1.68f,22}

};

cout<<"liu : "<<woman[0].name<<"\n"<<woman[0].height<<"\n"<<woman[0].age<<endl;

//不能这样写:cout<<woman[0]和woman[0][1],这两种都是错误的。

return 0;

}

093432_0L0Y_3244697.png

 

9.存储数据:

信息存储在何处?

值是多少?

类型是什么?

 

指针,存储值得地址,不存储值本身。

如何获取变量a的地址:使用&(地址操作符)。&a就是a的地址。

093452_1nND_3244697.png

看来,系统是倒着存储的,先存变量b,在c,在a,从地址可以看出,8的地址最小,6的地址最大。

那就从8开始,8是int,占4个字节,(0018ff3c-0018ff38=4个字节);5.6是double,占8个字节。

电脑是64位操作系统。

写代码时,指定数组长度为20,这是编译阶段决策;等程序跑起来的时候,在指定数组的长度为200,这是运行阶段决策。

C++:使用关键字new请求正确数量的内存,以及使用指针跟踪新分配的内存位置。

*操作符,被称为间接值或解除引用操作符。结合指针,可以得到该地址处存储的值。

a是一个指针,则a表示一个地址,*a表示存储在该地址的值。*a与常规int 变量等效。

 

#include <iostream>

using namespace std;

int main()

{

int a = 6;

int *p;//声明一个指针p,其类型是int,p指向int类型,p是指针(地址),*p不是指针,是int

// * 左右的空格是可选的

p = &a;//此时,p保存a的地址。将p的值初始化为&a : int *p = &a.

cout<<"a="<<a<<endl;

cout<<"a的地址="<<&a<<endl;

cout<<"p="<<p<<endl;

cout<<"*p="<<*p<<endl;

cout<<"p的地址="<<&p<<endl;

*p = *p+1; //*p是p处的值,修改p的地址处的值,加1

cout<<"a="<<a<<endl;

return 0;

}

093514_nMoz_3244697.png

危险!!!

long *p;

*p = 2333;

p虽然没有被初始化,但p依旧是一个指针,只是不知道它指向计算机的哪里,那么,2333被放在哪里呢?不知道。。。这是最隐匿,最难以跟踪bug的可能来源!

请将指针初始化为一个确定的,适当的地址。

将地址赋值给指针:

错误示范:

int *p;

p = 0x80000000;

正确的:

int *p;

p = (int *) 0x80000000;

p是int型的地址,但并不意味着p本身的类型是int。

 

10.使用new来分配内存

int *pt = new int;

程序员告诉new,需要为那种类型分配内存,new找到长度正确的内存块,并返回内存块的地址。程序员将该地址赋值给指针。

分配的内存块没有名字,叫数据对象。

#include <iostream>

using namespace std;

int main()

{

int *pt = new int;

*pt = 1024;

cout<<"*pt="<<*pt<<" pt="<<pt<<endl;

 

double *pd = new double;

*pd = 1024.03;

cout<<"*pd="<<*pd<<" pd="<<pd<<endl;

cout<<sizeof pt<<endl; //sizeof后面带不带()都行

cout<<sizeof (pd)<<endl;

cout<<sizeof *pt<<endl; //int是4个字节,下面double是8个字节

cout<<sizeof *pd<<endl;

return 0;

}

093529_GIbt_3244697.png

 

11.使用delete释放内存

int *pt;

...

delete pt;

请配对使用new和delete,否则发生内存泄漏(memory leak)!

只能使用delete释放new分配的内存!

 

用new创建动态数组:在程序运行时,使用数组,分配内存;不使用,不分配。

//动态数组

#include <iostream>

using namespace std;

int main()

{

double *p3 = new double [10];

//创建指针p3,他指向包含10个元素的内存块中的第一个元素地址。

p3[0] = 0.1; //使用动态数组很简单,用指针名当数组名就可以了。

p3[1] = 0.2;

p3[2] = 0.8;

cout<<p3[1]<<endl;

p3 = p3+1; //此时,p3指向第二个元素。

cout<<p3[0]<<" "<<p3[1]<<endl;

p3 = p3-1;

delete [] p3; //释放内存,需要让p3-1,回到原来。

return 0;

}

093555_g3gk_3244697.png

 

2.指针和数组:把指针当作数组名!

数组名代表第一个元素的地址

#include <iostream>

using namespace std;

int main()

{

double wa[3] = {10000.1,20000.0,30000.0}; //wa初始地址:0018FF30,简称30

short stacks[3] = {3,2,1}; //stacks初始地址,28;28,29这两个字节写3,;3a,3b写2;

double *pw = wa; //数组和指针等价!!!此时,pw是wa 0号元素的地址

//存在 wa = &wa【0】

short *ps = &stacks[0];

 

cout<<"pw="<<pw<<"\n*pw="<<*pw<<endl; //wa的地址和wa数组的0元素的值

pw = pw +1; //指针+1,即所指向的地址+8,因为pw指向double,8个字节,即指向wa的1元素

cout<<"pw="<<pw<<"\n*pw="<<*pw<<endl<<endl; //wa+1的地址和wa数组的1元素的值

 

cout<<"ps="<<ps<<"\n*ps="<<*ps<<endl;

ps = ps + 1; //指针+1,即所指向的地址+2,因为pw指向double,2个字节

cout<<"ps="<<ps<<"\n*ps="<<*ps<<endl<<endl;

 

cout<<"stacks[0]="<<stacks[0]<<" stacks[1]="<<stacks[1]<<endl;

cout<<"*stacks="<<*stacks<<" *(stacks+1)="<<*(stacks+1)<<endl;

//再次证明数组和指针等价,且证明stacks[1] = *(stacks+1)

cout<<"wa 的 size ="<<sizeof(wa)<<"\n pw 的 size ="<<sizeof(pw)<<endl;

//指针的size不是其所指向类型的大小。比如pw所指type是double,但是其size是4

return 0;

}

093626_wH80_3244697.png

注意: *(stacks+1) ≠ *stacks+1,后者将*stacks所指向的值加1.

 

3.#include <cstring>

strlen(),返回字符串长度

strcpy(),将字符串从一个位置移动到另一个位置

 

#include <iostream>

#include <cstring>

using namespace std;

int main()

{

char animal[20] = "bear";

const char *bird = "wren"; //不可更改bird所存储的地址和*bird处的值!!

char *ps;

 

cout<<animal<<" and "<<bird<<endl; //数组名和指针都输出了字符串,都是字符串的地址

cout<<"enter a kind of animal:\n";

cin>>animal; //改变animal,如输入cat

//不用使用字符串常量bird或未初始化的的指针ps来接收输入

ps = animal; //animal是指针,指向“cat”的c,赋值后,ps指针也指向cat的c

cout<<ps<<"\n";

cout<<animal<<" "<<(int *)animal<<endl;

//给cout提供一个指针,打印指针地址;若指针类型为char *,则显示指向的字符串。

//要显示字符串地址,要将这种指针强制转换为另一种指针类型,如int *

cout<<ps<<" "<<(int *)ps<<endl<<endl;

 

ps = new char[strlen(animal) +1 ]; //+1,包含空字符。使用new,不浪费内存空间。new,根据字符串长度指定所需空间

strcpy(ps,animal); //第一个参数,ps,目标地址;第二个参数,animal,要复制的字符串的地址

cout<<animal<<" "<<(int *)animal<<endl;

cout<<ps<<" "<<(int *)ps<<endl;

delete [] ps;

return 0;

}

运行:

bear and wren

enter a kind of animal:

cat

cat

cat 0018FF34

cat 0018FF34

 

cat 0018FF34

cat 00332998

Press any key to continue

 

2017.7.10

1.使用new创建动态结构

#include <iostream>

using namespace std;

struct infla //结构声明;新类型infla

{

char name[20]; //结构成员

float volume;

double price;

};

 

int main()

{

infla *ps = new infla; //创建一个未命名的infla类型,将其地址赋给ps指针

cout<<"enter name of infla item:";

cin.get(ps->name,20);

//现在不知道结构名,只知道结构地址,不能用.访问成员;用->箭头成员操作符,ps指向name

cout<<"enter volume:";

cin>>(*ps).volume; //*ps,被指向的值-结构本身。所以*ps是一个结构,

cout<<"enter paice :";

cin >>ps->price;

cout<<"name:"<<(*ps).name<<endl;

cout<<"volume:"<<ps->volume<<endl;

cout<<"price:"<<ps->price<<endl;

delete ps;

return 0;

}

 

运行:

 

enter name of infla item:liu huo

enter volume:1.5

enter paice :25.66

name:liu huo

volume:1.5

price:25.66

Press any key to continue

 

2017.7.11

 

1.论i++和++i的不同:

对操作数i的影响是相同的,只是时间不同

就像吃饭前付钱和吃饭后付钱!

#include <iostream>

using namespace std;

int main()

{

int a=20,b=20;

cout<<"a="<<a<<" b="<<b<<endl;

cout<<"a++="<<a++<<" ++b="<<++b<<endl;

cout<<"a="<<a<<" b="<<b<<endl;

return 0;

}

运行:

a=20 b=20

a++=20 ++b=21

a=21 b=21

Press any key to continue

 

2. ++i,前缀递增;--i,前缀递减;*,解除引用操作符;三者优先级相同,

后缀递增,i++;后缀递减,i--;这二者优先级高于上面

double arr[5] = {1,2,3,4,5};

double *pt = arr;

++pt,地址+1,指向arr【1】

*++pt,地址再+1,指向arr【2】,然后取值,

++*pt,先取值,在将值+1

*pt++,先将pt地址+1,然后再取值

 

3.因为定时器的关系,先写队列和双向列表,所以先看函数和类

函数分两类:有无返回值

没有:

void functionName(parameterList) //parameter,参数,list,包含参数类型和数量

{

函数过程

return; //optional,可选的

}

 

有返回值:

typeName functionName(parameterList)

{

statement,声明,陈述

return value; //value不能是数组,但可以是其他任何

}

 

#include <iostream>

using namespace std;

const int size = 8;

int sum_arr(int arr[] ,int n); //求数组元素的和,arr为数组名(形参),n为数组长度。但实际,arr是一个指针!!指针指向int数组的第一个元素,可以用int arr[] ;指针指向一个独立的值,用指针用法

int main()

{

int cookie[size] = {1,2,4,8,16,32,64,128};

int sum = sum_arr(cookie,size); //并未将cookie数组传给sum_arr,只传递了数组的地址

cout<<"array sum is :"<<sum<<endl;

return 0;

}

 

int sum_arr(int arr[] ,int n)

{

int total = 0;

for (int i = 0;i<n;i++)

total = total+arr[i];

return total;

}

/*cookie == &cookie[0],数组名就是第一个元素的地址

sum_arr(cookie,size) ,cookie是第一个元素的地址,数组元素为int,所以,cookie的类型为int指针,即int *,

所以函数头要这么写:int sum_arr(int arr[] ,int n) ---》int sum_arr(int *arr ,int n),arr是数组名

 

 

4.

指向常量的指针pt

int age = 40;

const int *pt = &age

pt指向const int,不能使用pt修改值40,*pt的值为const

 

5.数组实现的队列

//使用循环数组实现队列;用一个数组空间区别队空(front=rear)和队满(rear+1=front);

#include <iostream>

using namespace std;

template <class T>

class cycleQueue

{

private:

unsigned int m_size; //队列大小

int m_front; //队首

int m_rear; //队尾

T* m_data; //指针

public:

cycleQueue(unsigned size) //初始化??

:m_size(size),

m_front(0),

m_rear(0)

{

m_data = new T[size]; //动态建立数组,将地址赋给一个指针

}

~cycleQueue() //析构函数,用于删除new创建的数组

{

delete [] m_data;

}

 

bool isEmpty() //是否为空

{

return m_front == m_rear;

}

 

bool isFull() //是否满了

{

return m_front == (m_rear + 1)%m_size;

}

 

void push(T ele) //入队

{

if(isFull())

cout<<"队列是满了!!\n";

else {

m_data[m_rear] = ele;

m_rear = (m_rear + 1)%m_size;}

}

 

bool pop() //出队

{

if(isEmpty())

{

cout<<"队列是空的\n";

return false;

}

T tmp = m_data[m_front];

cout<<"所删除的元素下标:"<<m_front<<" 元素是:"<<tmp<<endl;

m_front = (m_front + 1)%m_size;

return true;

}

 

void bian()//遍历队列

{ cout<<"开始打印队列:\n";

cout<<"size:"<<m_size<<endl;

for(int i=m_front;i<m_rear;i++)

cout<<m_data[i]<<endl;

cout<<"打印完毕!\n";

}

 

void front()//队首元素

{

if ( isEmpty() )

cout<< "队列是空的!!\n";

else

cout<<"队首元素是:"<< m_data[m_front]<<endl;

}

void len()//元素长度

{

cout<<(m_rear-m_front+m_size)%m_size<<endl;

}

};

int main()

{

cycleQueue<int> q(5);

q.push(1);

q.push(2);

q.push(3);

q.push(4);

q.bian();

q.front();

for (int i = 0; i < 4 ; i++)

q.pop();

q.push(5);

q.push(5);

q.push(5);

q.len();

q.pop();

q.pop();

q.pop();

q.pop();

return 0;

}

 

运行:

开始打印队列:

size:5

1

2

3

4

打印完毕!

队首元素是:1

所删除的元素下标:0 元素是:1

所删除的元素下标:1 元素是:2

所删除的元素下标:2 元素是:3

所删除的元素下标:3 元素是:4

3

所删除的元素下标:4 元素是:5

所删除的元素下标:0 元素是:5

所删除的元素下标:1 元素是:5

队列是空的

Press any key to continue

 

 

2017.7.12 周三

1.

char word [10] = "aate";

想知道word中的字符是不是mate,用word == ”mate“是不行的!!

因为word是数组名,代表数组地址,用 ” “ 的字符串也表示字符串的地址名。

解决方法:

使用srtcpm()函数,接收两个字符串地址作为参数,这意味着参数可为指针,字符串常量,字符数组名。

相同,返回0;第一个的字母顺序在第二个之前,返回负数;之后,返回正数

 

#include <iostream>

#include <cstring>

using namespace std;

 

int main()

{

char word[10] = "?ate";

for (char ch = 'a';strcmp(word,"mate");ch++)

{cout<<word<<endl;

word[0] = ch;}

cout<<"after loop ends,word is "<<word<<endl;

return 0;

}

运行:

?ate

aate

bate

cate

date

eate

fate

gate

hate

iate

jate

kate

late

after loop ends,word is mate

Press any key to continue

 

2.string类,可以使用关系操作符(>,<,=之类的)直接比较

#include <iostream>

#include <string>

using namespace std;

 

int main()

{

string word = "?ate";

for (char ch = 'a';word != "mate";ch++) //不相等,继续执行;相等,返回0,退出循环

{cout<<word<<endl;

word[0] = ch;}

cout<<"after loop ends,word is "<<word<<endl;

return 0;

}

结果与1的相同。

 

3.让屏幕暂停

/*让子弹飞一会

函数clock(),返回程序开始执行后所用的系统时间

ctime==time.h,提供一个符号常量,CLOCKS_PER_SEC,每秒包含的系统时间单位数

系统时间/CLOCK_PER_SEC=秒数

ctime将clock_t当作clock()的返回类型的别名,可以将变量声明为clock_t类型,编译器把他转换为long,unsigned long等

*/

#include <iostream>

#include <ctime>

using namespace std;

 

int main()

{

cout<<"enter the delay time,in second:";

float secs;

cin>>secs;

clock_t delay = secs * CLOCKS_PER_SEC; //delay,要等待的系统时间

cout<<"startint\a\n";

clock_t start = clock();

//cout<<"start 是啥??-----》"<<start<<endl;

while ( clock()-start<delay )

//cout<<"开始等:\n"<<clock()<<" "<<start<<" "<<delay<<endl;

;

cout<<"done \a\n";

return 0;

}

//注释代码为了理解程序。delay是2000,start就是开始等待的时间,4455,最后,2000+4455=6455,与结果很接近

 

有未注释的2行code,

结果:

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

开始等:

6451 4455 2000

done

Press any key to continue

上面有好多未能复制

 

注释代码:在stertint等了3s

enter the delay time,in second:3

startint

done

Press any key to continue

 

4.类型别名:将word作为int的别名,word类型的值仍未int

第一种,#define BYTE char ,编译时用 char代替所有BYTE.

第二种,typedef char byte,用byte作为char的别名。

 

5.循环和文本输入

(1)cin输入

//输入一个字符,显示一个字符,计算总共输入多少个字符

//cin,读取char值是,忽略空格和换行;发送给cin的输入被缓冲,按下回车键,整个字符序列被发送给程序。

#include <iostream>

using namespace std;

 

int main()

{

char ch;

int count = 0;

cout<<"输入一个字符,按#停止\n";

cin>>ch;

while (ch != '#')

{

cout<<ch;

++count;

cin>>ch;

}

cout<<"\n"<<count<<endl;

return 0;

}

 

运行:

输入一个字符,按#停止

fsd f f fwfhgs #fsdk

fsdfffwfhgs

11

Press any key to continue

 

 

(2) iostream类包含一个成员函数,cin.get(ch),读取输入的下一个字符,将其赋值给变量ch。

//输入一个字符,显示一个字符,计算总共输入多少个字符

//cin,读取char值时,忽略空格和换行;发送给cin的输入被缓冲,按下回车键,整个字符序列被发送给程序。

#include <iostream>

using namespace std;

 

int main()

{

char ch;

int count = 0;

cout<<"输入一个字符,按#停止\n";

cin.get(ch);

while (ch != '#')

{

cout<<ch;

++count;

cin.get(ch);

}

cout<<"\n"<<count<<endl;

return 0;

}

运行:包含空格!

输入一个字符,按#停止

qwe fwt ghter #sbdkg

qwe fwt ghter

15

Press any key to continue

 

6.

输入一个值,表示有多少行,第一行包括1个*,第二行2个*,

每一行包含的字符数为行数,*不够,用>补够

#include <iostream>

using namespace std;

int main()

{

int num,i;

cout<<"enter want rows is \n";

cin>>num;

for (int a=1;a<=num;a++)

{

i = num-a;

for (int b=1;b<=i;b++)

cout<<'>';

for (int c=0;c<a;c++)

cout<<'*';

cout<<endl;

}

return 0;

}

 

enter want rows is

7

>>>>>>*

>>>>>**

>>>>***

>>>****

>>*****

>******

*******

Press any key to continue

 

2017.7.13

1.char指针变量,通过指向一个字符串的开始位置,来标识该字符串;

char指针数组,char * a[3]={"qwe","asd","zxc"},也可以标识一系列字符串,a[0],存储“qwe”的地址!

所以,cout<<a[0];结果是输出qwe,而不是qwe的地址。

 

2017.7.14

1.

字符函数库cctype

很尴尬,我没用#include <cctype>也跑出来了

#include <iostream>

#include <cctype>

using namespace std;

 

int main()

{

char ch;

int whitespace = 0;

int digits = 0;

int chars = 0;

int punct = 0;

int others = 0;

 

cin.get(ch);

while(ch != '$')

{

if(isalpha(ch)) //是不是字母,是就返回1,否返回0,下同

chars ++;

else if(isspace(ch)) //空白,按个计数。一个空格,2个制表,3个换行,总计为6

whitespace++;

else if(isdigit(ch)) //数字

digits ++;

else if(ispunct(ch)) //标点符号

punct++;

else

others++; //其他

cin.get(ch);

}

cout<<chars<<"\n"<<whitespace<<"\n"<<digits<<"\n"<<punct<<"\n"<<others<<endl;

return 0;

}

运行:

qwe rty

123 ,./\

%^&

$

6

5

3

7

0

Press any key to continue

 

 

2.条件操作符?:

5>3 ?4:99,如果5>3为true,表达式的值为4,false,表达式的值为99

 

3.switch,case

#include <iostream>

using namespace std;

void showmenu();

void cheap(); //便宜

void discount(); //打折

int main()

{

showmenu();

int choice;

cin>>choice;

while (choice != 4)

{

switch(choice)

{

case 1: cout<< "我是废话!\n";

break;

case 2: cheap();

break;

case 3: discount();

break;

case 4: cout<<"bye!\n";

break;

default: cout<<"没有这个选项!少侠请重新选过!!\n";

}

showmenu();

cin>>choice;

}

return 0;

}

void showmenu()

{

cout<<"please enter 1,2,3,or 4:\n"

"1,haha 2.cheap\n"

"3.discount 4.quit\n";

}

void cheap()

{

cout<<"便宜的!快来啊!来快活啊!\n";

}

void discount()

{

cout<<"5折,5折,全部5折,跳楼大甩卖!\n";

}

 

093726_XB52_3244697.png

 

 

使用字母

while (choice != 'd')

{

switch(choice)

{

case 'a': cout<< "我是废话!\n";

break;

case 'b': cheap();

break;

case 'c': discount();

break;

case 'd': cout<<"bye!\n";

break;

default: cout<<"没有这个选项!少侠请重新选过!!\n";

}

showmenu();

cin>>choice;

}

 

4.写入到txt中

 

#include <iostream>

#include <fstream>

using namespace std;

int main()

{

char a[50]; //字符数组a,接收一个最大50的字符串

int b;

double c,d;

ofstream outFile; //声明ofstream对象,命名为outFile

outFile.open("霸王.txt"); //将outFile与文件进行关联

//只输入文件名,就是在本目录找到这个txt,清空里面的东西,重新输入;没找到,就新建一个;也可以输入目录,记得目录要使用 \,如这种:

//outFile.open("C:\\Users\\00105230\\Desktop\\c++\\霸王.txt"); //可行!

 

//输入a,b,c,d

cout<<"输入 a:\n";

cin.getline(a,50);

cout<<"输入 b:\n";

cin>>b;

cout<<"输入 c:\n";

cin>>c;

d = 0.965*c;

 

cout<<fixed; //不使用科学记数法输出double,使用一般形式输出

cout.precision(2); //小数部分显示精度为2位

cout.setf(ios_base::showpoint);//强制显示浮点数小数点后的0

cout<<"输出a,b,c,d:\n";

cout<<a<<endl<<b<<endl<<c<<endl<<d<<endl;

 

//cout能用的,outFile都可以用

outFile<<fixed; //不使用科学记数法输出double,使用一般形式输出

outFile.precision(2); //小数部分显示精度为2位

outFile.setf(ios_base::showpoint); //强制显示浮点数小数点后的0

outFile<<"输出a,b,c,d:\n";

outFile<<a<<endl<<b<<endl<<c<<endl<<d<<endl;

 

outFile.close(); //()不需要参数,因为outFile已经同特定的文件关联起来了

return 0;

}

运行:

输入 a:

liu huo huo

输入 b:

33

输入 c:

1.83

输出a,b,c,d:

liu huo huo

33

1.83

1.77

Press any key to continue

 

文件里:

输出a,b,c,d:

liu huo huo

33

1.83

1.77

 

 

5.读取txt

使用ifstream对象和get()读取一个字符;用ifstream对象和getline()读取一行字符

使用ifstream和eof(),fail()判断输入是否成功

对象cin本身被用作测试条件,如果最后一个读取操作成功,他将被转换为bool的true,否则转换为false。ifstream的对象也一样

cin.fail()来判断当前的输入和预期是否相同,如果不同的话cin.fail()返回true

当输入流读取失败时,它会把字符放回原处,等待下次读取

 

#include <iostream>

#include <fstream>

#include <cstdlib>

#include <windows.h> //用于防治屏幕闪退

using namespace std;

//const int size = 60; //此处必须有 = ,使用define则不需要。

#define size 60 //使用define,不需要等号,注意,后面没有 ; !!!

int main()

{

char a[size];

ifstream inFile; //声明对象inFile

cout<<"输入一个目录:";

cin.getline(a,size);

inFile.open(a); //输入的目录中必须包含文件名

 

if(!inFile.is_open()) //方法is_open(),成功打开文件,返回true;否则返回false;旧版本,检查文件打开用good()

{

cout<<"打开文件失败!请检查目录是否出错,文件是否存在!\n";

exit(EXIT_FAILURE); //exit()在cstdlib中定义。在cstdlib中,还定义了一个同操作系统通信的参数值EXIT_FAILURE,exit(),终止程序

}

double value;

double sum = 0.0;

int count = 0;

inFile>>value; //从文件中第一次读取一个double,直到遇到第一个不属于浮点字符的字符

while (inFile.good())

{

count++;

sum += value;

inFile>>value;

}

 

if (inFile.eof())

cout<<"文件读取完毕!\n"; //全部读取完毕,就显示这个。

else if (inFile.fail())

cout<<"数据不匹配导致输入终止!\n"; //若文件中有非浮点字符,遇到,停止,即使后面还有数字,也不会在读取。

else

cout<<"未知原因导致输入终止!\n";

if(count==0)

cout<<"no data processed!\n";

else

{

cout<<"总共有___个数:"<<count<<endl;

cout<<"和是:"<<sum<<endl;

cout<<"average:"<<sum/count<<endl;

}

inFile.close();

//Sleep(5000); //暂停5s

return 0;

}

运行:

输入一个目录:C:\\Users\\00105230\\Desktop\\c++\\霸王.txt

文件读取完毕!

总共有___个数:8

和是:263.799

average:32.9749

Press any key to continue

 

6.局部变量,在程序执行过程中自动被分配和释放

某函数计算数组元素之和,参数:

 

2017.7.17

类的声明:stock是这个新类的类型名

class Stock

{

private:

类数据成员,只能通过公有成员函数访问数据

public:

类函数成员

};

声明stock类型的对象

stock a;

 

2.strncpy(s2,s1,n);从s1字符串中复制n个字符到s2中,s1<n,则在s2后补空字符;>,加一句 s2[n]='\0';

 

3.char * a::b()

类a有一个名为b()的成员函数,该函数返回char指针;

b()是一个char *类型的函数,也是一个属于a类的char *函数

 

2017.7.18

1.回顾字符串

  • 两种方式,第一种,c风格。char str1[size] = "abcde",字符串str1大小为6,因为在e后还有一个‘\0’空字符。str1也是字符串的地址。使用#include <cstring>,strlen(str1)可得到str1中可见字符的大小,为5。sizeof(str1)得到str1的字节数。
  • cin,使用空白(空格(ascii为32),制表,换行)来界定字符串边界。
  • cin,成员函数get(),getline()都读取一行,直到到达换行符为止。随后,getline()丢弃换行符,get()将换行符保存在了输入序列。
  • cin.getline(str1,5),str1为字符数组名,5为字符串大小,读取4个字符,最后一个放‘\0’;

2017.7.19

1.定时器,allot(),分配,队列块号是0-19999,现在0出队,0号块号就分配给了定时器;1出队,定时器就是1号;0号到时,free(),回收块号,0入队;

2.

#include <iostream>

using namespace std;

int main() //无论这里是int还是void,只要底下有一个return就行,虽然int时会警告

{

int a;

cin>>a;

if(a<0)

{cout<<"xx!\n"; //输入的小于0,就不再执行if之后的,也就是不输出b

return ;

}

int b=3;

cout<<b<<endl;

}

 

2017.7.21

1.

类的私有成员不能被对象直接访问。

一般将成员数据设为private,将实现接口设为public

class Huamn() //类名首字母大写,声明一个Human类

{

int weight; //类默认私有,私有成员只能通过在类中设置的接口函数来访问。

};

int main

{

Human liuWei; //定义一个人类的对象liuWei

liuWei.weight; //错误!!!不能用对象直接访问私有成员

}

 

2.声明与定义是不同的:

声明:void set(int) ,告诉编译器函数返回的类型是void和参数类型是int

定义:void set(int i) //定义要给对象分配内存,要实现函数的功能

{cout<<"i="<<i<<endl; }

 

3.在类中,一般要将成员函数的声明与定义分开。

在程序中,调用函数首先跳转到函数部分,执行完毕后,在调回到调用函数的下一句。调用100次,就跳转100次,怎么解决这个问题?

使用内联函数:使用关键字inline声明函数是内联函数,然后将函数代码复制到调用函数处,调用的时候就不在跳转,用一次复制一次,这回增大程序的体积,因为调用100次就复制100次。但是,如果函数代码很短,就不会有这种顾虑。

inline int set (int) ; //声明一个内联函数,返回类型为int,参数也是int型。

int set (int i) //定义函数就不需要加inline了。

{

return i;

}

int main()

{

cout<<set(2)<<endl; //编译阶段,编译器将set()函数的代码复制到这一行。

}

如果在类中,函数的声明与定义写在一起,该函数自动成为内联函数。

 

4.一般将类的声明写在 .h 文件中,类的实现写在 .cpp 中,声明a.h,在cpp中就写

#include "a.h"

为什么这样搞?

因为使用者并不关心你怎么实现这个功能的,他只关心他能用到什么功能,看.h文件就够了。

 

5.不想让成员函数修改成员变量(数据)的值,就将函数声明为const。

void print () const;

 

class Huamn() //类名首字母大写,声明一个Human类

{

public:

void print () const { cout<<weight<<endl; }

void set(i) const { weight = i; } //编译器报错!!因为该函数试图修改私有成员变量weight。

private:

int weight; //类默认私有,私有成员只能通过在类中设置的接口函数来访问。

};

int main

{

Human liuWei; //定义一个人类的对象liuWei

liuWei.weight; //错误!!!不能用对象直接访问私有成员

}

 

6.构造函数:对类的所有对象进行初始化的函数。

如一个长方形类中,不没有构造函数,新建的长方形对象就没有长宽,那如何构造长方形呢??

 

若你没有定义构造函数,系统自动创建一个构造函数,没有参数,不执行任何功能,只用于构造一个对象

Rectangle () { }

 

class Rectangle //长方形

{

public :

Rectangle (int l , int w ) { length = l , width = w ;} //构造函数,名称和类名相同,没有返回值!

Rectangle () { } //因为已经定义了有参数的构造函数,想在定义无参的构造函数,就要自己定义一个默认的构造函数!

private:

int length;

int width;

}

int main()

{

Rectangle a(3,4); //定义一个长方形对象a,他会自动调用构造函数,初始化a为长3宽4

Rectangle b; //创建一个对象b,该对象未初始化,调用默认构造函数

}

 

7.析构函数,在对象被销毁后,清除对象所占用的内存空间,也就是清除由构造函数创建的内存。

一个类,只能有一个析构函数。

class A

~A() { } //析构函数,名称与类名相同,没有参数,~用于区别构造函数。

对象数组:

A a[2] ; //定义2个成员对象,以此为a【0】,a【2】

 

8.数组名==指针

#include <iostream>

using namespace std;

 

const int size = 8;

int sum_arr(int * arr,int n); //int * arr == int arr[]

//不要愚蠢到使用(int arr[n] )来传递参数

int main()

{

int a[size] = {1,2,4,8,16,32,64,128};

cout<<"a的地址是:"<<a<<endl;

cout<<"a的大小是:"<<sizeof a<<endl;

int sum = sum_arr(a,size);

cout<<"8个数的总和是:"<<sum<<endl;

sum = sum_arr(a,4);

cout<<"4个数的总和是:"<<sum<<endl;

sum = sum_arr(a+4,4); //a是a[0]的地址;a+1是a[1]的地址;a+4是a[4]的地址

cout<<"总和是:"<<sum<<endl;

return 0;

}

 

int sum_arr(int *arr,int n)

{

int total = 0;

cout<<"验证a的地址:"<<arr<<endl;

for (int i=0;i<n;i++)

{

total = total +arr[i];

}

return total;

}

运行:

a的地址是:0018FF28

a的大小是:32

验证a的地址:0018FF28

8个数的总和是:255

验证a的地址:0018FF28

4个数的总和是:15

验证a的地址:0018FF38

4个数的总和是:240

Press any key to continue

 

9.数组函数

先说说if(!cin)的情况:

输入流有四种状态,各值为1 时表示

good 下一操作可能成功

bad 流已破坏

eof 遇到结束

fail 下一操作将失败

当eofbit、badbit、failbit三个标记位均为0时表示流状态正常

 

看一个小代码:

int input;

if   (cin   >>   input)

            cout   <<   input   <<   endl;

       else

            cout   <<   "input   error"   <<   endl;

       if   (!cin)

            cout   <<   "input   error"   <<   endl;

       else

            cout   <<   input   <<   endl;

运行,输入1,输出1,1

cin将1给input,cin为true,正常,3个标记位为0,(可用类似检测 cin.fail() ),good是1,。

输入123a,输出123,123。此时,输入流中还有一个a

cin将123给input,cin为true,正常,3个标记位为0,good是1,。

如果在运行一次代码,(代码写两遍),输入流中的第一个字符是a,a与input不匹配,“   >>   ”无法抽取, 抽取操作符“   >>   ”函数返回的cin对象,其failbit标记位被置为1(goodbit标记位被置为0)  ,cin的自测为False,if  判定条件为false;且导致下一个if语句:  if   (!cin)    中, cin对象为false, !cin  为true。

 

 

2017.7.24

1.接上次,数组函数

先说说cin.get()

cin.get(字符数组名,数组大小),此方法类似cin.getline().

cin.get()不会丢弃换行符。遇到换行符停止读取。

cin.get(),没有任何参数,调用可读取的下一个字符(包括换行)!可用cin.get()处理换行符。

cin>>yaer,会将换行符留在输入队列中。

 

//数组函数

 

#include <iostream>

using namespace std;

int fill_array (double ar[],int limit);

 

int main()

{

double array[5];

int a = fill_array(array,5); //调用的数组大小为5,则只能输入5个元素。

cout<<array<<endl; //这样不能输出数组元素!array是数组名,也是第一个元素的地址,所以这行输出一个地址!

for(int i=0;i<a;i++) //打印数组

{

cout<<array[i]<<"\t";

}

 

return 0;

}

int fill_array (double ar[],int limit) //填充数组,ar为数组名;limit,要输入的元素个数;返回实际输入的个数

{

double temp;

for (int i=0;i<limit;i++)

{

cout<<"enter value :"<<i+1<<endl; //输出i+1,元素个数

cin>>temp;

if(!cin) //检测cin是不是输入错误,进入if,说明输入错误

{

cin.clear(); //清除输入流中的错误状态,你输入的是abc,abc不是int,cin将更改状态到false,cin.clear()的默认参数为:ios::goodbit

cout<<"bad input:"<<temp<<endl;

while(cin.get() != '\n') //清除输入流,等同于cin.sync();

continue;

cout<<"bad input!\n"<<temp<<endl;

break;

}

else if (temp < 0) //输入的元素必须>0

break;

ar[i] = temp;

}

return i;

}

运行:

enter value :1

2

enter value :2

4

enter value :3

5 6

enter value :4

enter value :5 //注意这行输入,输入7y,本来不应该通过,但是cin只提取了7,y还留在输入队列中,所以这一刻cin为true。

7y

0018FF20

2 4 5 6 7 Press any key to continue

 

 

完成版的数组函数:

//数组函数

 

#include <iostream>

using namespace std;

int fill_array (double ar[],int limit);

void show_array(const double ar[],int n); //显示数组,不需要返回值,所以是void

void revalue(double r,double ar[],int n); //修改函数。将元素与r相乘。

 

int main()

{

double array[5];

int a = fill_array(array,5); //调用的数组大小为5,则只能输入5个元素。

show_array(array,a);

int multiplier;

cout<<"乘数:"<<endl;

cin>>multiplier;

revalue(multiplier,array,a);

cout<<"再次输出数组:\n";

show_array(array,a);

 

return 0;

}

int fill_array (double ar[],int limit) //填充数组,ar为数组名;limit,要输入的元素个数;返回实际输入的个数

{

double temp;

for (int i=0;i<limit;i++)

{

cout<<"enter value :"<<i+1<<endl; //输出i+1,元素个数

cin>>temp;

if(!cin) //检测cin是不是输入错误,进入if,说明输入错误

{

cin.clear(); //清除输入流中的错误状态,你输入的是abc,abc不是int,cin将更改状态到false,cin.clear()的默认参数为:ios::goodbit

cout<<"bad input:"<<temp<<endl; //temp是一个int型,所以temp=之前的,上一个数字,如果程序刚开始就输入一个字符,就随机显示一个数

while(cin.get() != '\n') //清除输入流,等同于cin.sync();

continue;

cout<<"bad input!\n"<<temp<<endl;

break;

}

else if (temp < 0) //输入的元素必须>0

break;

ar[i] = temp;

}

return i;

}

 

void show_array(const double ar[],int n) //指针ar指向常量数据,不可修改。n,元素个数

{

for(int i=0;i<n;i++)

cout<<"第"<<i+1<<"个元素是:"<<ar[i]<<endl;

}

void revalue(double r,double ar[],int n)

{

for(int i=0;i<n;i++)

ar[i] *= r;

}

 

运行:

enter value :1

23

enter value :2

45

enter value :3

67

enter value :4

89

enter value :5

12

第1个元素是:23

第2个元素是:45

第3个元素是:67

第4个元素是:89

第5个元素是:12

乘数:

2

再次输出数组:

第1个元素是:46

第2个元素是:90

第3个元素是:134

第4个元素是:178

第5个元素是:24

Press any key to continue

 

运行:

enter value :1

2

enter value :2

4

enter value :3

65

enter value :4

ty

bad input:65

bad input!

65

第1个元素是:2

第2个元素是:4

第3个元素是:65

乘数:

2

再次输出数组:

第1个元素是:4

第2个元素是:8

第3个元素是:130

Press any key to continue

 

 

2.//数组区间

/*

double a[20] 定义一个大小为20个元素的数组a

数组名a指向第一个元素;a+19,指向第19个元素;a+20指向最后一个元素的后面。

*/

#include <iostream>

using namespace std;

const int size = 8;

int sum_ar(const int * begin,const int * end); //求数组和

int main()

{

int array[size]={1,2,4,8,16,32,64,128};

int sum = sum_ar(array,array+size);

cout<<"数组和:"<<sum<<endl;

sum = sum_ar(array,array+3);

cout<<"数组和:"<<sum<<endl;

sum = sum_ar(array+4,array+8);

cout<<"数组和:"<<sum<<endl;

 

return 0;

}

int sum_ar(const int * begin,const int * end)

{

const int * pt;

int total=0;

for(pt=begin;pt!=end;pt++)

total += *pt;

return total;

}

 

运行:

数组和:255

数组和:7

数组和:240

Press any key to continue

 

3.二维数组

int data[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

data第一个元素是一个数组,由4个int值组成。

在内存中,按先行后列存储,先放第一行1234,其后依次。

在int sum( int (*ar2) [4] )定义中,

int (*ar2) [4] :一个指向由4个int组成的数组的指针

int *ar2[4]: 一个由4个指向int的指针组成的数组。

 

4.字符数组所形成的字符串,由‘\0’空字符结束。将字符串作为参数传递的是地址。

//字符数组

/*

计算某字符在字符串出现几次?

*/

#include <iostream>

using namespace std;

int c_str(const char * str,char ch);

 

int main()

{

char aaa[15]="asdafgaaafa";

char *b="sdfbasb"; //整个字符串也表示地址

int as = c_str(aaa,'a'); //字符数组aaa有多少a

int bs = c_str(b,'b');

cout<<as<<" "<<bs<<endl; //输出6,2

return 0;

}

int c_str(const char * str,char ch)

{

int count=0;

while(*str) //字符串值到了最后的‘\0’,就退出

{

if(*str==ch)

count++;

str++;

}

return count;

}

 

5.

//字符数组

/*

返回字符串的地址

*/

#include <iostream>

using namespace std;

char * buildstr (char c,int n); //buildstr是函数名,char *表示函数返回一个char类型的指针!

int main()

{

int times;

char ch;

cout<<"输入一个整数:\n";

cin>>times;

cout<<"输出一个字符:\n";

cin>>ch;

char *ps = buildstr(ch,times);

cout<<ps<<endl;

delete [] ps;

ps = buildstr('+',20);

cout<<ps<<"-vVVv-"<<ps<<endl;

delete [] ps;

return 0;

}

 

char * buildstr (char c,int n) //将字符c复制n次

{

char *pstr = new char[n+1]; //需要n个字符空间+1个空字符空间

pstr[n]='\0'; //字符总个数为n+1,数组大小为0 ~ n

while (n-- > 0) //n--,先使用这个值,然后再将n-1,若n=3,则3>0,下面n就成了2.

pstr[n]=c;

return pstr;

}

运行:

输入一个整数:

46

输出一个字符:

Z

ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

++++++++++++++++++++-vVVv-++++++++++++++++++++

Press any key to continue

 

6.

//函数和结构1

/*

声明一个结构,成员为小时和分钟。从a地到b地需3h45min,从b到c要5h40min,求路程总和

*/

#include <iostream>

using namespace std;

struct travel_time

{

int hours;

int mins;

}; //别忘了还有一个;!

const int mins_per_hr = 60;

travel_time sum(travel_time t1,travel_time t2);//路程花费总时间

void show(travel_time t);

 

int main()

{

travel_time day1 = {3,45};

travel_time day2 = {5,40};

travel_time trip = sum(day1,day2);

cout<<"two-day total:";

show(trip);

travel_time day3 = {2,55};

cout<<"tfree-day total:";

show( sum(trip,day3) );

return 0;

}

 

travel_time sum(travel_time t1,travel_time t2) //路程和

{

travel_time total ;

total.mins = (t1.mins+t2.mins) % mins_per_hr;

total.hours = t1.hours + t2.hours + (t1.mins +t2.mins )/mins_per_hr;

return total;

}

 

void show(travel_time t)

{

cout<<t.hours <<" hours,"<<t.mins <<" minutes \n";

}

运行:

two-day total:9 hours,25 minutes

tfree-day total:12 hours,20 minutes

Press any key to continue

 

7.

//直角系坐标与极坐标的转换-->函数传递结构体本身

/*

描述屏幕上某点位置,一种方法指出该点相对于原点的水平x和垂直y偏移量

另一种,指出他偏移原点的距离和角度

*/

#include <iostream>

#include <cmath> //数学中的函数,也可用math.h,求平方根

using namespace std;

struct rect //直角坐标系

{

double x;

double y;

};

struct polar //极坐标

{

double distance; //距离

double angle; //角度

};

 

 

polar rect_to_polar(rect xy); //直角系 转 极坐标

void show_polar(polar dapos); //显示极坐标,不过将角度由弧度转为角度

 

int main()

{

rect rplace;

polar pplace;

cout<<"输入x和y坐标:";

while(cin>>rplace.x>>rplace.y) //输入错误,跳出循环

{

pplace = rect_to_polar(rplace);

show_polar(pplace);

cout<<"next two nums(q to quit)"<<endl;

}

cout<<"风雪与眼眸\n"; //当时听的是姚贝娜的随它吧。

return 0;

}

 

polar rect_to_polar(rect xy)

{

polar answer;

answer.distance= sqrt(xy.x * xy.x + xy.y *xy.y);

answer.angle = atan2(xy.y , xy.x) ; //atan2函数由x和y求出角度,C++中cmath的角度单位是弧度!

return answer;

}

void show_polar(polar dapos)

{

const double rad_to_deg = 57.29577951; //弧度*180/3.1415926=角度,180/3.1415926=57.295

cout<<"distance:"<<dapos.distance<<endl;

cout<<"angle :"<<dapos.angle * rad_to_deg<<endl;

}

 

运行:

输入x和y坐标:30 40

distance:50

angle :53.1301

next two nums(q to quit)

59 60

distance:84.1487

angle :45.4815

next two nums(q to quit)

45 q //q被留在了输入队列中,cin状态变为false,退出循环!

风雪与眼眸

Press any key to continue

 

运行:

输入x和y坐标:34 67r

distance:75.1332

angle :63.0939

next two nums(q to quit)

风雪与眼眸

Press any key to continue

 

2017.7.25

1.//直角系坐标与极坐标的转换-->函数传递结构体的指针,结构体地址:&结构体的变量名

/*

描述屏幕上某点位置,一种方法指出该点相对于原点的水平x和垂直y偏移量

另一种,指出他偏移原点的距离和角度

*/

#include <iostream>

#include <cmath> //数学中的函数,也可用math.h

using namespace std;

struct rect //直角坐标系

{

double x;

double y;

};

struct polar //极坐标

{

double distance; //距离

double angle; //角度

};

 

 

void rect_to_polar(rect* xy,polar* answer); //直角系 转 极坐标

void show_polar(const polar* dapos); //显示极坐标,不过将角度由弧度转为角度

 

int main()

{

rect rplace;

polar pplace;

cout<<"输入x和y坐标:";

while(cin>>rplace.x>>rplace.y) //输入错误,跳出循环

{

rect_to_polar(&rplace,&pplace);

show_polar(&pplace);

cout<<"next two nums(q to quit)"<<endl;

}

cout<<"风雪与眼眸\n";

return 0;

}

 

void rect_to_polar(rect* xy,polar* answer) //传递一个直角坐标的结构体指针;需要修改指针所指的值,不用const;直接修改,不用返回,用void;所以还要传递极坐标的指针

{

answer->distance= sqrt(xy->x * xy->x + xy->y *xy->y);

answer->angle = atan2(xy->y , xy->x) ; //atan2由x和y求出角度,C++中cmath的角度单位是弧度!

}

void show_polar(const polar* dapos) //dapos是一个指针,指向polar类型;加const,不改变指针所指的值

{

const double rad_to_deg = 57.29577951; //弧度*180/3.1415926=角度,180/3.1415926=57.295

cout<<"distance:"<<dapos->distance<<endl; //指针使用间接成员操作符->

cout<<"angle :"<<dapos->angle * rad_to_deg<<endl;

}

 

运行:

输入x和y坐标:30 40

distance:50

angle :53.1301

next two nums(q to quit)

q

风雪与眼眸

Press any key to continue

 

2.//将string作为参数传递

/*

string是一个类

*/

#include <iostream>

#include <string>

using namespace std;

 

const int size = 5;

void display(const string sa[],int n); //显示string数组的内容。sa是数组名也是指针,形参sa是一个指向string对象的指针

int main()

{

string list[size]; //数组list下的每个元素都是一个string对象

cout<<"输入"<<size<<"个字符串:\n";

for (int i=0;i<size;i++)

{

cout<<i+1<<": ";

getline(cin,list[i]);

}

cout<<"your list:\n";

display(list,size);

 

 

return 0;

}

 

void display(const string sa[],int n)

{

for (int i=0;i<n;i++)

cout<<i+1<<": "<<sa[i]<<endl;

}

运行:

输入5个字符串:

1: 1

//这一行是回车,输完第一个后,第二个提示不出来,只好按下回车,结果第二个输入就成了空。这是编译器的问题,vc6.0有一个bug:输入语句与输出语句不能同步。可以直接输入并按下回车。

2: 2

3: 3

4: 4

5: 5

your list:

1: 1

2:

3: 2

4: 3

5: 4

Press any key to continue

 

3.//递归:自己调用自己,调用即压栈,全部调用完毕,该弹出所保存的数据

 

#include <iostream>

using namespace std;

void countdown(int n);

int main()

{

countdown(4);

return 0;

}

void countdown(int n) //保存n,返回n

{

cout<<"this is "<<n<<",it at "<<&n<<endl; //显示数及数所保存的地址

if(n>0)

countdown(n-1); //调用自己

cout<<"返回中,,,"<<n<<",it at "<<&n<<endl;

}

运行:

this is 4,it at 0018FEF8

this is 3,it at 0018FEA0

this is 2,it at 0018FE48

this is 1,it at 0018FDF0

this is 0,it at 0018FD98

返回中,,,0,it at 0018FD98

返回中,,,1,it at 0018FDF0

返回中,,,2,it at 0018FE48

返回中,,,3,it at 0018FEA0

返回中,,,4,it at 0018FEF8

Press any key to continue

 

4./*

用递归画画--糊里糊涂

*/

 

#include <iostream>

const int len = 66;//字符数组的长度,第66个元素是'\0'

const int divs = 6; //递归调用6次

void divide(char ar[],int low,int high,int level); //字符数组,头,尾,函数本身次数

int main()

{

char ruler[len];

int i;

for (i=0;i<len-2;i++) //标号0-64为空格

ruler[i]=' ';

ruler[len-1]='\0';//结尾为空字符

int max = len-2;

int min = 0;

ruler[max]=ruler[min]='|';

//至此,66个字符,(下标)0和64为‘|’,65为'\0',其余为空格

std::cout<<ruler<<std::endl;

for (i=0;i<divs;i++)

{

divide(ruler,min,max,i);

std::cout<<ruler<<std::endl;

for(int j=1;j<len-2;j++)

ruler[j]=' ';

}

return 0;

}

 

void divide(char ar[],int low,int high,int level)

{

if(level<0)

return;

int mid = (high+low)/2;

ar[mid]='|';

divide(ar,low,mid,level-1); //左半边

//divide()还要调用自己两次,调用一次导致2个调用,然后4个调用,8,如果递归层次太多,递归很糟糕,如果很短,精致而简单

divide(ar,mid,high,level-1); //右半边

}

运行:

| |

| | |

| | | | |

| | | | | | | | |

| | | | | | | | | | | | | | | | |

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Press any key to continue

 

5.函数指针

获取函数的地址:

函数名就是函数地址。

a()是一个函数,a是函数地址

p(a),p函数的参数是a函数,在p函数内可调用a函数

pp(a()),pp函数的参数是a函数的返回值

 

声明函数指针:

声明一个函数:double pam(int);

声明函数指针:double (*pf) (int); 将函数声明的pam改成(*pf),pam是函数,(*pf)也是函数;pf为指向函数的指针。

()的优先级高于*,

(*pf) (int),pf是一个指向函数的指针

*pf (int),pf()是一个返回指针的函数

将函数地址赋给指针:

double pam(int);

double (*pf) (int);

pf = pam;

 

 

2017.7.26

1.内联函数

在函数声明,定义之前加inline;内联函数不可递归,不能太大,最好一行

c语言使用预处理语句:#define 提供宏---内联代码的原始实现

#define a (x) x*x //计算平方的宏,没有参数传递,而是文本替换!

aa=a(3)-->aa = 3*3;

 

2.引用变量,已定义变量的别名,用作函数的形参

&,两种用法:一,指示变量地址;二,声明引用变量

/*

引用,变量有两个名称,rats和rodents

*/

 

#include <iostream>

using namespace std;

int main()

{

using namespace std;

int rats = 10;

int & rodents = rats; //rodents的类型为int &,即int变量的引用,从此,rodents与rats互通有无。

//引用声明时,必须初始化;指针,可以先声明,在赋值。

cout<<"rats="<<rats<<endl;

cout<<"rodents="<<rodents<<endl;

cout<<"rats address="<<&rats<<endl;

cout<<"rodents address="<<&rodents<<endl; //引用的变量的地址

rodents++;

cout<<"rats="<<rats<<endl;

cout<<"rodents="<<rodents<<endl;

cout<<"rats address="<<&rats<<endl;//rats加1之前与之后,地址肯定不变;且引用的地址也不变。4个地址相同

cout<<"rodents address="<<&rodents<<endl;

 

int a=100;

rodents = a;//将另一个变量赋给引用的变量,rodents变成100,rats也成了100;但是,rodents的地址不变!

cout<<&a<<" "<<&rodents<<" "<<&rats<<endl;

return 0;

}

运行:

rats=10

rodents=10

rats address=0018FF44

rodents address=0018FF44

rats=11

rodents=11

rats address=0018FF44

rodents address=0018FF44

0018FF3C 0018FF44 0018FF44

Press any key to continue

 

int a=100;

int * pt = &a;

int & b = *pt; //将b初始化为*pt,即100,b引用的是a!

 

3./*

交换两个数

*/

 

#include <iostream>

using namespace std;

void swapq(int & a,int & b); //按引用传递

void swapa(int * a,int * b); //按指针传递

void swapz(int a,int b); //按值传递;但是传递的是值得拷贝,所以无法更改原来的数据

int main()

{

int a = 100;

int b = 77;

swapq(a,b);

cout<<a<<" "<<b<<endl;

swapa(&a,&b); //传递两个地址

cout<<a<<" "<<b<<endl;

swapz(a,b);

cout<<a<<" "<<b<<endl;

return 0;

}

void swapq(int & a,int & b)

{

int temp;

temp = a;

a = b;

b = temp;

}

void swapa(int * a,int * b)

{

int temp;

temp = *a;

*a = *b;

*b = temp;

}

void swapz(int a,int b)

{

int temp;

temp = a;

a = b;

b = temp;

}

运行;

77 100 //交换后a=77,b=100

100 77 //交换后,a=100,b=77

100 77 //交换失败

Press any key to continue

 

 

4./*

引用当参数

*/

 

#include <iostream>

#include <string>

using namespace std;

 

string ver1(const string & a,const string & b);//ver1函数返回string对象,两个参数是string对象的引用,const指出不能改变两个参数

const string & ver2(string & a,const string & b);//ver2函数返回string类型的引用

const string & ver3(string & a,const string & b); //错误示范

 

int main()

{

string s1,copy,result;

cout<<"enter a string :";

getline(cin,s1);

copy = s1;

cout<<"init s1="<<s1<<endl;

result = ver1(s1,"***");//第二个参数是c风格字符串,类型:const char *,string类定义了char *到string的转换,所以可用

cout<<"first,s1="<<s1<<" result="<<result<<endl;

result = ver2(s1,"%%%"); //注意,此时,s1被改变,并且s1被赋给result

cout<<"second,s1="<<s1<<" result="<<result<<endl;

s1 = copy;

result = ver3(s1,"%%%"); //导致不能通过编译或警告,运行将导致程序崩溃

cout<<"second,s1="<<s1<<" result="<<result<<endl;

return 0;

}

 

string ver1(const string & a,const string & b)

{

string temp;

temp = b+a+b;

return temp;

}

const string & ver2(string & a,const string & b)

{

a = b+a+b;

return a;

}

const string & ver3(string & a,const string & b)//返回一个string对象,但是这个函数在调用完之后就会被释放内存,返回的引用无处可引!

{

string temp;

temp = b+a+b;

return temp; //warning C4172: returning address of local variable or temporary,返回的地址 局部变量或临时的

}

运行:

enter a string :woaini 输入完后回车,在回车一次才进行,估计是vc6的问题

 

init s1=woaini

first,s1=woaini result=***woaini***

second,s1=%%%woaini%%% result=%%%woaini%%%

Press any key to continue

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3244697/blog/1492491

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值