C++学习日记

C++学习日记

基础的入门知识:

**(EasyX) 绘图库

(写代码时一行一般仅仅书写一条语句!!!)
1.#include
C ++提供了各种标头,每个标头都包含程序正常运行所需的信息。该特定程序要求头文件

行首的数字符号(#)面向编译器的预处理器。在这种情况下,#include告诉预处理器包括

头文件定义的标准流对象用于输入和输出数据。

2.定义变量直接一行一个变量定义,并在定义时直接初始化。

3.C ++编译器忽略空白行。
通常,空行用于提高代码的可读性和结构

4.不管程序做什么,每个C ++程序的入口都是main(),且有且只有一个主函数main()!!!!1
注:此处的main()相当于一个指针,告诉电脑此处是一个函数!()代表着函数,空括号表示其支持传参的功能

5.我们常常使用命名空间std,该命名空间包括C++标准库的功能

6.花括号{}指示函数的开始和结束,也可以称为函数的主体。括号内的信息指示函数在执行时的功能

7.提取符:>> (输入) 插入符:<<(输出) 两者都可以连续使用
系统规定的键盘输入流对象名为cin
系统规定的标准输出流对象为cout

8.在C++中,分号; 用于终止语句。每个语句必须以分号结尾。
它表示着一个逻辑表达式的结尾!

9.在函数中使用return语句进行结尾,如果不使用return语句,则C++编译器会在main()函数的末尾隐式插入“return 0”
注:非0值表示异常终止!!!

10.C++中 单引号’ ’ 常常用来表示单个字符
双引号” ”则用来表示一个字符串
字符串的长度可以很长,但是
字符的长度是有限制
的,通常为单个字符)

  1. & 是取值符用来在C++平台中查找值的内存存储位置

12.当在主函数main()前未声明定义的时候,要引用相关的函数的时候可以使用 :: (双冒号)以此来表明此处的代码块是所引用函数的成员函数!!

13.在进行定义和运算的时候要注意是什么类型,同时在进行除法运算的时候两个整数相除容易造成数据的丢失,所以可以将两个整数转化为浮点数去运算,否则结果可能会出现0的情况

14.C++运行时输出的出现的-nan(ind) (not a number ),一般是出现了错误的运算。

15.EOF被包含在iosream库之中,它的值为 -1

常用的I/O类库操纵符

dec: 数值数据采用十进制表示
hex: 数值数据采用十六进制表示
oct: 数值数据采用八进制表示
ws: 提取空白符
endl: 换行符
ends: 插入空字符
setprecision(int): 设置浮点数输出的有效数字个数
setw(int): 设置域宽

(域宽为整数,一个域宽代表了一个字符即一位)

进制表示法

1.十进制。如56。
2. 十六进制,以0x开头,比如0x7a。输出十六进制hex关键字格式化,如cout< 3. 八进制,以0开头,比如030。输出八进制用oct关键字格式化,如cout<

C++输入遇到空格或者回车就停止输入的方法

注:通过使用cin的get()方法或者是getline()方法进行输入

#include
using namespace std;
 
int b[10];
int main() 
{
	int i=0,a;
	while(cin>>a){
		b[i++]=a;
    	if(cin.get()=='\n') break;	
	} 
	for(i=0;i<10;i++) cout<<b[i]<<" ";
}

缺省(即默认值)

1.main()缺省为int
2.char缺省为有符号的

换行符

在C++编辑中末尾使用endl操纵器进行换行,使用插入符<<将其与内容隔开
(此处的换行也可以使用\n换行符来实现)

空格符

在C++编码中使用 “ ” 在输出时代表着空格

注释(使代码更具有可读性)

方法一:使用//+注释的内容
方法二:使用 (/* 和 */)进行注释,中间的内容都将被计算机视为注释
(注意第二种方法的符号的前后位置)

注:为了使代码更具有可读性,使用大括号时,大括号内的语句可以采用缩进两格的方式使代码更具有可读性!!

布尔型

布尔型和整数可以相互转化
False:0
True:1(除了0以外,其余数字均代表真!)

bool 进行布尔变量的声明
注:如果将整数值指定给布尔值0,0将变成False,并且其余所有的非0值都将变为True!

实型

float: 单精度浮点数,4个字节。一般为7位有效数字
double: 双精度浮点数,8个字节。一般为15位有效数字

注:在C++中,在默认情况下,输出一位小数,最多只能输出6位有效数字(这和数据类型无关)

科学记数法表示小数

float f2= 3e2 // 3*10^2

逻辑运算符

!(逻辑非) (处理单个操作数,反其逻辑状态)
&& (逻辑与) (等于Python中的and)
|| (逻辑或) (等于Python中的or)

位运算符(仅作用于整数)

<< (左移)

(右移)
& (按位与) 两位上只有都是1才能与出来1

~ (按位求反) 0变1, 1变0
^ (按位异或) 0^0=0 0^1=1 1^1=0
| (按位或) 0|0=0 0|1=1 1|1=1

三目运算符

“ ? :” 是C++里面的唯一的三目运算符

<表达式1>?<表达式2>:<表达式3>

解释:当表达式1为真,运行表达式2
当表达式1为假,运行表达式3;

变量(变量中不允许有空格或者是特殊字符!)

同Python中的变量定义,创建变量位置会保留一个内存位置,用于存储所需要的变量值!!!!
注:与python 不同的是C++在定义变量的时候要注明变量的数据类型,是整数还是字符串还是浮点数;若有多个相同类型的变量可以在一个声明中定义它们,中间使用逗号隔开(一般不建议这样,编程的原则为简单明了,尽量一行一个语句代码

有两种已知的命名约定:
帕斯卡:标识符中的第一个字母和随后连接的每个单词的第一个字母都大写。例如:BackColor

驼峰写法:标识符的第一个字母是小写的,每个后续连接单词的第一个字母都是大写的。例如:backColor

MicroSoft建议:对于简单的变量使用camelCase,而对于比较高级的命名规则使用PascalCase。

Var类型

在C++里面定义类型,int、float、double、char等定义时需要准确地知道定义的数据的类型,而var可以根据所赋值的变量去定义数据的类型;

格式: var 变量名 =变量值

注意点:
1.必须在定义的时候初始化,不可以 var a; a=0 的这种形式
2.var在定义的变量必须是局部变量
3.初始化完成之后不可以再给变量赋与初始化的值不同的变量值

cin和cout

其中cin是用来提取数值信息,即用来获得用户的信息!!!配合提取符>> 一块使用!!
cout则用来输出,则是进行在屏幕上输出字体

预处理(宏定义)

C++ 开头有以#开头的命令,他们是预处理命令!
(进行宏定义的时候,要注意#define和语句块之间的空格,要注意字母的大写以区分代码中的常量,使代码更具有可读性)

的引用之随机数的调用

1.随机数的产生要将rand()函数和srand()函数配套使用,rand()用来产生随机数而srand()函数则用来将rand()随机数的种子初始化!

(rand()函数产生的随机数是伪随机数,如果不将其初始化的话,rand()函数产生的一直是系统默认的初始值,一般为1)

常常使用srand(time(NULL))来将rand()种子初始化,使rand()函数的随机数随时间而发生改变!!
注:要引用库

2.rand()h函数产生具有一定范围的随机数的通用公式为:
1).随机整数的公式: a + rand % n

a为起始数,n为随机数的个数!!
例如: 随机数的范围为[ a, b) (rand()%(b-a))+a
2).若要得到浮点数的随机数

*a + (double)(rand())/RAND_MAX n

a为随机起始数,n为几个浮点数的区间范围,即 [a,n+a] 的范围区间
其中RAND_MAX是电脑中库的一个字符常量!!

注:此处要引用

(由于集成环境的不断成熟,有的编译器中的 iostream 库中已经包含了其他许多库中的函数和常量值的使用)

引用和的预处理操作

1.//平方 pow()
int a = pow(4,2);// 4的平方=16
2.//开方
int b = pow(4,0.5);// 4的平方根=2
int c = sqrt(4);// 4的平方根=2
3.//整数绝对值
int c = abs(b-c);
4.//浮点数绝对值
double d = fabs(b-c);
注意:
(使用**#include或#include** 是等价的,
预定义之后才能进行这一系列操作!)

定义符号常量的方法

1.使用宏定义的方法来定义符号常量
#define 字符 …
2.使用关键字const,例如:
const 字符 …
(一个符号常量可以作为一个只读变量,在定义符号常量时必须初始化,否则会出现编译错误!!!!)

浮点数常量

缺省为double
有两种表示方法:
1.小数表示法
2.科学表示法,在小数表示法后面加上E或e表示指数,指数部分可正可负,但都是整数!!!!

字符与ASCII码值间的转化

使用char()和int()进行转化

字符常量

使用一个单撇号括起一个字符来表示,例如:‘A’

注:当数字字符转为相应的数字时即用 数字字符减去 **‘0’**即可以转换为相应的数字;

字符串常量

字符串常量常常用双撇号括起,在C++语言之中,凡是字符串都有一个结束符,该结束符用 ‘\0’ 表示
(‘\0’ 同时又表示空字符)
注:
1.一个字符常量被存放在内存中仅占一个字节,而字符串至少占两个字节以上
2.字符常量具有加法和减法运算,而字符串常量不具有这种运算!

除法

整数和整数相除返回的是整数值!!!!!!!

增量运算符和减量运算符

   **++  :与   x=x+1       --:与  x=x-1**

增量运算符有两种表达形式:
1.x++ (在使用x之前增加x的值)
2.++x (先使用x的值再将其递增)
两种所表达的意思基本上是相等的,但是两者在赋值于变量的时候存在着差异和不同!!!

数组(Array)

<类型> <数组名>[ <大小1> ][ <大小2> ]

1.[ ] 方括号表示数组的维! 有几个方括号代表了有几维;
C++的数组下标从0开始,并且各个元素在内存中是按其下标的升序顺序连续存放的!
2.{}方括号中声明的元素数目不能超过方括号中的元素数目!
3.如果忽略数组的大小,将创建一个足以容纳初始化的数组!
4.每个数组的成员都有一个索引(索引总是以0为开头),要使用它们的时候,该索引可以精确的确定元素的特定位置!(数组中的每个成员都可以被重新赋值)

枚举

enum 枚举名 {枚举表} 枚举变量

注:多个枚举符之间、多个枚举变量之间要用逗号隔开

1.输出某个枚举变量的值总是整型数值,而不是枚举符!!!!

指针(4个字节)

1.指针定义了一个地址,每个变量都有一个地址;
2.可以使用 &(与号运算符访问该地址,该运算符表示内存中的地址)
&指针
1.指针是一个变量,它的值是另一个变量的地址。
2.在C++中,指针有助于使某些任务更容易执行。其他任务,如动态内存分配,在不使用指针的情况下无法执行。
3.所有指针共享相同的数据类型-------一个表示内存地址的长十六进制数。

4.不同数据类型的指针之间的唯一区别是指针指向的变量的数据类型。
*指针
星号用于声明指针(与乘法使用的星号相同),但是,在该语句中,星号用于将变量指定为指针。

以下是有效的指针声明:

int *ip; // 指向整数的指针
double *dp; // 指向double的指针
float *fp; // 指向浮点的指针
char *ch; // 指向字符的指针

就像变量一样,我们给指针一个名称并定义指针指向的类型。
星号符号可以放置在数据类型旁边,或者变量名,或者中间。

(&):返回其操作数的内存地址。
**(*)的内容(或取消引用):返回变量在其操作数指定的地址处的值。**例如:

int var = 50;
int *p;
p = &var;
cout << *p << endl;
输出 50 (变量p内置地址对应的值)
注:p是var 存储值50的地址,*p返回变量在其操作数指定的地址处的值。

  1. 运算符(*)还可以表示取消对变量指针的引用,由此其表示的与变量完全相同!

数组和指针的应用

牢记指针一定是一个地址值,而*为解引用,是指针存储的地址处的内容
(static 是说明符,说明一个数组是静态类的数组;)
1.数组的名称为每个数组首元素的地址值,它是一个常量指针,不可以被改变。而变量指针可以进行相关的赋值并改变其值

  1. 数组使用指针访问的公式为 :(二维数组) 注:可以自己放缩到一维或更大维的数组
    *( *( a+ i)+j ) = a [ i ] [ j ]

3.当数组为字符数组时,输出的时候必须以 ‘\0’ 为结束符,若指针未明确指定到某个字符,而是指定到某个字符串的其中一个字符时,将自动输出至结束符 ’\0’ 所在的地方!!!!!

int a[3] = { 1,2,3 };
int* pa[3];
pa[0] = &a[0];
pa[1] = &a[1];
*(pa+2)= a + 2;
cout << pa<< endl;
cout << *pa[0] << endl << **(pa + 1) << endl << *pa[2] << endl;

注:数组的名称为一个常量指针,是不可变的,其值为数组首个元素存放地址的值,当数组为指针数组时,数组的每个元素的值为一个地址值

5.字符串的首个字符为字符串的首地址

  1. **s[ i ]=p+++ 即等于 s[ i ]=p+;p++;
    s[ i ]=
    (++p)+1 即等于 p++; s[ i ]=p+1;

字符指针

即使用字符串的首地址为char 类型的指针进行赋值,这个操作在C语言中是可行的,但是在C++中确是会报错的,因为我们定义的是一个指针变量,而字符串的首地址为一个常量指针;
这是我们要定义指针的话,只需要这么做:
const char a;
a = “aabced”;
*
对于*a来说,是不可改变的,但是a是一个可以变化的指针;

条件语句if

1.同Python 中的if语句相同用法
if 语句指定的条件需要使用分号,配合else使用

2.条件运算符(三目)
布尔条件一?条件二:条件三;
注:条件一真时执行条件二,为假时执行条件三;

  1. if 语句后可跟一个可选的 else if 、else 语句,这可用于测试多种条件。
    当使用 if… else if …else 语句时,以下几点需要注意:
    一个 if 后可跟多个else,所有的else…if 语句必须在else之前。
    注:一旦某个 else if 匹配成功,其他的 else if 或 else 将不会被测试
    (else…if 等价于 elif ,即在上一个if要求的条件外和自己要求的条件内的两者的并集)

注:if条件中有多个条件时要分开来写并用&&来连接

多条件分支的switch和case语句

switch() 和case语句配合使用!!!
1.switch语句根据一系列值(称为case)测试变量,以确定它是否等于其中的任何一个值!
switch (表达式)
{
case value1:
语句1
break;
case value2:
语句2
break;
}
2.switch计算表达式以确定它是否等于case语句中的值,如果找到匹配项,它将执行这种情况下的语句!!
3.当switch语句中,没有一个case被确定为true时,可以使用可选的default case 来执行任务!
将没有任何事例与switch表达式匹配时,将执行default默认语句的代码!
且其必须出现在switch的末尾!!!
4.break用于中断符合情况的case语句,防止出现落空的情况!

保留数字的操作

开头时输出使用预处理 #include
setprecision(n):
保留n位有效数字

cout< :
(或cout<

保留小数点后n位数字

注:当使用这些语句后以后的浮点数都将采用这种方式去表达!保留的操作采用四舍五入的方式

注意:当计算机中计算结果四舍五入发现结果不对,可能是因为出现了精度损失的原因,所以我们可以在结果的后面加上不影响结果的特别小的多位小数数字一次来提高结果的准确度!

while循环

1.一个语句块结束后使用;进行未知次数的循环;
while (条件句)
{
语句块
}

2**.do…while 循环**,大致与while循环一样,但是do …while 循环至少循环一次
do {
语句块
} while (条件)

即若while中的条件为假,do中的代码仍执行一次!!

for循环(循环特定次数)

for(init 初始化 ;condition 条件 ;increment 自增)
{
循环语句
}

注:如果不需要,可以省略init初始化和increment自增语句,但分号是必须的

1.init初始化步骤首先执行,接着是condition条件,increment语句更新循环控制变量;然后循环的主体就会重复自身!
2.当条件为真时,循环的主体就会开始第一次循环,第一次循环结束之后才会再进行控制循环变量的更新

求一个整数值各个位上最大的数

使用递归的方法来求得各个位上的数字,并用if语句去判断各位上的数字的最大值
例如:(n/100) %10 为百位上数字的值
(n/ 某个位上的10的幂次方)% 10 为 相应数位上的数字的值

复合赋值运算符

+=(加赋值)
-=(减赋值)
&=(与赋值)
^= (异或赋值)
|= (或赋值)

cin错误标志位的处理

(cin的标志位信息是个字节)

badbit ; failbit ; eofbit ;
每个I/O 定义了三个iostate类型的常数值,分别表示特定的位模式;
1.badbit 标志系统级的故障 iostate的值为4;
2.failbit 标志可恢复级的错误 iostate的值为2;
3.eofbit 已经到达文件尾但是没有找到需要输入的数据,eofbit的值为1;
4.goodbit 值为0;

cin.rdstate() 获取标志变量的值
若cin出现异常,则必须重置标志。否则无法执行下一次的cin操作;
cin.clear() 重置错误标志;
cin.sync() 清除错误缓冲区;

sizeof运算符

sizeof运算符确定并返回类型或变量的大小(以字节为单位)

sizeof 不仅可以用于确定类型的字节数大小,还可以用于确定数组的大小;

数组

1.相同类型的数据的有序集合!(有序指的是地址的有序)
2.定义一个数组的时候,存在预分配内存的这一步操作,也就是要求编译者在定义的时候必须明确定义数组类型的个数!!

定义动态数组

1.定义一维的动态数组:
首先使用 new 符为一个未知数组开辟空间
*int size;
cin>>size;
int p=new int [size];

delete [ ] p ;
(凡是动态的,即所需的内存量不知道的,必须要使用到指针去定义)

2.定义二维动态数组:
思想:先定义一个指针数组,然后再将指针数组里面的每一个数定义成一个一维的数组,
(这里要使用for循环,为你所需要的一位数组在分配空间,使用 new 符 )
当然这还是要靠指针来实现。
int size,line;
cin>>size>>line;
int
p=new int*[size];
for (int i=0;i {
p[i]=new int [line];
}**

注:不管是几维的数组,在为其分配完栈上的内存空间后,必须要将其占用的内存空间进行释放,否则会出现内存泄漏;
for(int i=0;i {
delete [ ] p[i]; //释放开辟出来的二维动态数组的内存空间
}
delete [ ] p; //释放开辟出来的指针的内存空间

注:这个操作删除的是个指针的内存空间;

C++的系统函数

图形处理函数的头文件——grapg.h

屏幕处理函数的头文件——conio.h

函数

(包括系统函数和自定义函数)
1.函数是一组执行特定任务的语句,可以在C++中重用代码函数,每一个有效的C++程序都至少含有一个函数–主函数main()
2.函数前会有定义类型的名称,比如int ,最后要求要返回一个整数值。void是定义无值状态的基本数据类型,这个时候函数可以没有返回值;
3.定义函数的语法:

返回类型 函数名 (参数列表)
{
函数体
}

返回类型:函数返回值的数据类型
函数名:函数的名称
参数:调用函数时,向参数传递一个值,此值称为实际参数或参数。参数列表是指函数参数的类型、顺序、和数量。
函数体:定义函数的功能语句集合;

函数的声明
1.当在使用函数前已经定义了函数的时候,这时就不再需要再去声明函数了;
如果在程序较为复杂的时候,我们函数的调用在前,定义在后,这时就需要对函数进行声明
2.声明的结构:
<类型> <函数名>(<参数表>)

(函数的声明必须在函数的使用之前)

函数的调用

大致有三种基本的调用 : 传值调用 传址调用 引用调用

传值调用:
不改变实参的值,仅仅进行形参的改变!
(开销大,先复制一套副本)

传址调用:(指针)
通过对地址值的直接使用来将实参的值进行改变
(开销小)

引用调用:
通过引用(对实参的别名)来直接将函数的实参进行改变
(兼具上面两个的特点和好处!)

当函数的参数为数组的情况

数组的元素不能是引用的

(此时改变被调用函数数组被改变时,实参的数组也会相应的发生改变!)

一、形参和实参都用数组
调用函数的实参用数组名,被调用函数的形参也使用数组名,
此时形参和实参共用内存中的同一个数组!

注:即被调用函数中改变了数组中的某个元素的值,对调用函数该数组中的该元素的值也会相应的发生改变!

二、形参和实参都用对应数组的指针
(当为了为了防止数组相应的值被改变,应使用const 指针说明其不可修改!)
在使用数组的指针作为函数的的参数时,可以形参和实参都是用指针,也可以一个用指针,另一个使用数组!

注意:数组名是一个常量指针(其地址为指向该数组的首元素的地址值)

当函数的参数是结构体的情况!

一、直接使用结构体本身作为函数参数的情况
注:这种适合于情况较少,数据类型不多的结构体类型
(一般不用,因为数组是没有办法进行直接拷贝的)

二、将结构体的指针作为参数传递给函数!

void deal_student(student* s)
{
	cout<< s->no << " " << s->name << " " << s->score << " "<<endl;
	cin >> s->score;

}


int main()
{
	student s={1,"xyz",100};
	deal_student(&s);
	cout << s.no << " " << s.name << " " << s.score << " "<<endl;
	
}

传址会改变结构体的相应的结构的内容!!!

当函数需要返回多个返回值的操作时!

注:在C++中只能返回一个数,而不能返回多个值或者是数组!

一、定义一个Bool类型的函数,进行传参的操作

//布尔类型的函数,使用传址操作进行值的改变
bool max_min_of_array(int array[], int length, int* max1, int* min1)
{
	if (array == NULL)
	{
		return false;
	}
	else
	{
		int max = array[0]; int min = array[0];
		for (int i = 0; i < length; i++)
		{
			if (max < array[i])
			{
				max = array[i];
			}
			if (min > array[i])
			{
				min = array[i];
			}
		}
		*max1 = max;
		*min1 = min;
		return true;
	}
}
int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9 };
	int max = 0;
	int min = 0;
	max_min_of_array(a, 9, &max, &min);
	if (max_min_of_array(a, 9, &max, &min))
	{
		cout << max << " " << min << endl;
	}
}

二、使用数组,返回一个数组的头指针,利用数组的头指针以及数组地址值连续的特点,来检索其余多个返回值!

内联函数

以空间换取时间
(增加目标代码的增加为代价来换取时间的节省!)

内联函数的定义方法:
使用关键字 inline <类型> <函数名> (参数)

优化:该种函数在编译时被替代,而不是像一般函数那样在运行时被调用!

注意点:
1.在内联函数内不允许使用循环语句和开关语句,否则按非内联函数处理!(也就是说内联函数的代码实现一般是较为简单的代码体!)
2.内联函数的定义必须出现在内联函数第一次被调用之前!
3.类结构体中所有在类体内定义的成员函数都是内联函数!

函数的重载

1.函数重载允许你有多个相同名称的多个函数,只要他们具有不同的参数!!
注:重载函数的参数个数、参数类型或参数顺序三者之一必须有一个不同!!!
(若仅为函数的返回值不同则编译的时候会产生错误!)

2函数重载时函数的定义必须因参数列表中的参数的类型和数量而异!!!

3.不能重载只因返回类型不同而不同的函数声明

4.函数重载的规则:
1).函数名必须相同
2).仅仅是函数返回的类型不同不足以成为函数的重载
3).函数的返回类型可以相同也可以不同
4).参数的列表不同(重载函数的参数个数、参数类型或参数顺序三者之一必须有一个不同)

函数的嵌套和递归使用

嵌套使用:函数调用使可以在调用别的函数,

也可以返回别的函数!

函数的递归使用:
在调用函数的过程中间接的或直接的再次出现被调用的函数

缺点:在时间和空间的花费较多
(因为要花费较多的内存空间去存储中间的结果,在实际的应用中应该尽量的避免递归!)

例如:求菲波那挈数列的第8项

int Fibonacci(int n)
{
	int p = 0;
	if (n == 1)
	{
		return 0;
	}
	else if (n == 2)
	{
		return 1;
	}
	else
	{
		return  Fibonacci(n - 2) + Fibonacci(n - 1);
	}
}

int main()
{	
	
	cout << Fibonacci(8);
}

函数的 作用域

1、标识符只能在说明它或定义它的范围内是可见的,而在该范围之外是不可见的!

范围有大有小,最大的是整个程序,最小的是块,中间的有文件、类和函数!

2、在某个作用范围内定义的标识符在该范围内的子范围内可以重新定义该标识符!

按作用域的大小可以分为一下几类:

程序级:外部函数和外部变量

文件级:内部函数和外部静态类变量
函数级
块级

注:在某个作用域的标识符仅仅在当前的作用域有用,有可能标识符被多次重复定义,但是
在相应的作用域内就会被覆盖掉!

全局变量和局部变量

局部变量:在一个函数、代码块内部定义的变量
(存放在栈内存上,在函数结束后自动销毁)

全局变量:在每个模块的头文件中使用 extern去声明的变量

(全局变量存储在静态存储区域,定义时可以使用 global_ 定义以说明其是全局变量。
在定义全局变量的时候要注意出现表达不明确的情况的时候可能是因为 定义的全局变量和计算机本身的存储变量相撞

注:
1.外部变量:定义在函数体外的,定义是不加任何任何存储类说明的变量!
(一个程序中外部变量只能被定义一次)
2. 全局变量(外部变量)可以被同一工程项目中其他文件用extern声明后调用,对其每次进行修改都会被保存。

(内存存放在静态内存区)

静态存储变量
(静态存储区)

1.静态全局变量:
在全局变量前加static修饰。
(静态全局变量只能被本源文件使用,不能被其他源文件使用)

2.静态局部变量:
在局部变量前加static修饰。

动态存储变量: 程序在运行过程中动态申请内存的对象(例如 new )
(存放在 栈内存或者是 堆内存上,需要我们手动去销毁)

动态和静态内存

1.栈stack:所有的本地变量都占用栈中的内存。
(作为固定变量存堵在电脑中)

2.堆heap:在程序运行时可以使用的未使用的程序内存,以动态分配内存。 (临时的)

3.new操作符:为变量分配内存,该操作返回分配的空间地址;
例: new int 这将分配存储堆上整数所需要的内存大小,并返回该 地 址 ;

注:内存的赋予不局限于字符和数字,还可以是数组!
4.使用delete语句释放指针指向的内存,否则会导致内存泄漏,在程序关闭之前,内存将一直被分配!!
5.使用delete语句之后不会删除指针本身,但它会变成一个空的指针;
空指针是一个常量,其值为0;
注:删除之后你可以再重新为其赋予内存地址,但是其内存地址未赋值时其存储值为任意未知数!!!!

6.**(*p)**取消引用之后是一个具体的值或字符串,p 是指向存储变量的地址;

外部函数和内部函数

一般模块内同一个文件的叫内部函数。不同文件的叫外部函数。

1.内部函数:(静态函数)
在定义它的文件中可以被调用,而在同一程序中的其他文件中不可以被调用!
语法:
static <类型说明> <函数名> (参数表)

2.外部函数:
作用域在整个程序中的函数!
语法:
extern <类型说明> <函数名> (参数表)

C++语言的系统函数

不同的系统函数放在不同的 .h 文件之中
如: 字符串处理函数放在 string.h
屏幕处理函数放在conio.h
图形处理函数放在graph.h

字符串(字符数组的)处理函数

字符串长度函数 strlen(): 用来读取字符串的有效长度不包括(‘\0’)

字符串复制函数 strcpy_s(字符数组1**,**字符数组2):将数组2拷贝到数组1中
拷贝到‘\0’为止,注意数组1必须要能够容纳下数组2的字符串,否则就会出现数据混乱)

字符串连接函数 strcat_s(字符数组1**,**字符数组2):
找到上一个字符串 ‘\0’ 的地方,并替换为字符数组2

strncat_s(字符数组1,字符数组2,n)
在数组1的后面仅连接上数组2中的前n个字符!

字符串比较函数 strcmp(字符串1,字符串2):
比较两个字符串是否相等(比较的是ascii码值),
相等返回0;
不相等若前面的大,返回值为正(1),后面的大返回值为负(-1);

strncmp(字符串1,字符串2,N)
比较字符串1和字符串2的前N个字符是否相同,而后面的字符不再比较!

函数模板

函数模板将代表着不同类型的一组函数他们都是用相同的代码!这样就可以实现代码的重用,减少了空间的耗费!

语法:
template <参数化类型名表>
<类型>(函数名)((参数表))
{
函数体
}
参数化类型名表 又称为 模板参数表,多个表项目之间用逗号隔开!每一个表项称为一个模板参数!!

此函数的适用范围为对参数化函数体内所有结构和运算符都适用的对象!

template<class T>
void swap(T* a, T* b)
{
	T t;       //T为参数化的类型  
	t = *a;
	*a= *b;
	*b = t;
}

(class是修饰符,用来表示后面的标识符说明是参数化的类型名!)

注函数模板是模板函数的一个样板,他可以生成多个重载的模板函数,这些模板函数重用函数体的代码!

在使用函数模板进行输出的时候要进行显性的转化输出
<数据类型的输入输出>

默认函数参数

1.形式参数在函数中的行为类似于其他的局部变量,他们在进入函数时被创建,在退出函数时被销毁!
2.一旦定义了参数,在调用函数的时候就可以传递相应的参数!
3.若要返回值则要使用return语句进行返回值!

4.在定义函数的时候,你可以手动的去定义函数的的默认参数的值,调用函数的时候若未额外引入与其相关的参数,则会主动调用默认参数!
注:默认参数可以有多个参数!

格式化输出(printf)

(在有的IDE集成环境中iostream库文件包含了许多更多的环境,但是有的集成环境落后的话必须要引用
1 .printf()函数进行语句的输出
提示:C++使用**system( “pause “)**来暂停黑窗口在编写的c++程序中;
如果是窗口,有时会一闪就消失了;
如果不想让其消失,在程序中添加来使用进行窗口暂停!可以用来进行测试或debug时使用

2.(%+ 类型名称的简字母) 代表相应的格式化的输出

Class类和对象

对象:()创建对象的过程称为实例化
1.编程中,对象是一个独立的单元,每个对象都有自己的标识!
2.一个对象中可能包含其他的对象,但是他们仍然是不同的对象,对象有着用来描述他们的特征,这些特征也被称为属性,用来描述对象当前的状态!
3.每个对象都有着自己的行为方式
因此,从三个维度描述了面向对象编辑中的任何对象:
(名称)标识:identity 属性(特点):attribute 行为(功能):behavior

(面向对象的程序设计 oop ! )

Class类:
1.该类描述对象将是什么,但是又与对象本身是分开的,类可以描述为对象的蓝图、描述或者是定义
2.类里面可以看成是对象的集合,每一个类都有一个名称,并描述属性和行为,在编程中用类名指代我们正在出案件的一个特定类型的对象!
3.方法是类行为的另一个术语,基本上是属于类的函数
(类似于函数,他们可以被执行操作和返回值,方法是在类中声明的函数)

声明类

(在使用类之前必须先声明一个类 )
1.从关键字class开始定义类,后面跟着类名和类主体,用大括号括起来 (后面必须要有分号)
格式:
class 类名 { 类主体 };
类名前常常加上大写字母T以表示类名,区分其和函数名和对象;
2.在大括号内定义类主体中的所有的属性和行为(或成员或类的成员定义访问说明符)!!

3.public关键字定义的成员可以从类外部访问,只要它位于类对象范围内的任何地方

4.也可以将类的成员指定为 private (私有)或 protected(受保护)

5.在定义完一个类之后,要将类实例化之后(类似于变量的赋值)才能引用类中的函数体!
用于访问和调用对象方法的点分隔符(.)

抽象(abstration)

数据抽象是指向外界提供基本信息的概念,这是一个表示基本特性而不包括实现细节的过程
( 抽象作为其他面对对象的基础,如继承和多态性的基础!
可以理解为只提供一个本质特征而不包括其具体细节 )

封装

  1. 面向对象中,封装不仅仅意味着在一个类中简单的将属性和行为组合在一起,更是对限制对该类内部工作的访问隐藏类实现的详细信息。
    (仅显示其他应用程序组件有效运行应用程序所需的内容,其他的一切都看不见了,又叫做数据隐藏

2.使用封装后就不能从对象的外部直接更改,只能使用其他的方法访问(又称为 “ black boxing ” ),指关闭对象的内部工作区,除了我们想公开的部分

封装的好处:
控制访问 ; 使代码更灵活,依据需求更改 ; 更改代码的一部分而不影响其他的部分 ;

注意点:
1.在类的定义中如果既不指定private,也不指定public,则系统就默认为是私有的。

2.被声明为私有的(private)成员,只能被本类中的成员函数引用,类外不能调用(友元类除外)。

3.被声明为公用的(public)成员,既可以被本类中的成员函数所引用,也可以被类的作用域内的其他函数引用。

用protected声明的成员称为受保护的成员,它不能被类外访问(但可以被派生类的成员函数访问)

类构造函数constructor

1.类构造函数是类的特殊成员函数。每当在该类中创建新对象时,都会执行他们。
构造函数的名称与类的名称相同。它没有返回类型,甚至没有void。
例如:
class myClass {
public:
myClass() {
cout <<“Hey”;
}
void setName(string x) {
name = x;
}
string getName() {
return name;
}
private:
string name;
};

int main() {
myClass myObj;

return 0;
}
代码输出为: “Hey”
在创建myClass类型的对象时,构造函数将自动调用。

2.与其他成员函数相同的是,构造函数在类外定义时也需要明确指出是哪个类。

3.在创建多个不同的类对象的时候,可以多次使用构造函数,此时函数使用不同数量的参数

结构体struct

(结构体的长度为成员数据类型中的最长的字节)
1.定义结构体:
struct [<结构名>]
{
成员类型 成员名1
成员类型 成员名2


}
2.定义结构体变量:
struct <结构名> <结构变量名表>

3.结构变量成员的表示和赋值,引用

1).变量名. 成员名
2).变量指针名 -> 成员名
3).(*<变量指针名>).成员名
4).<数组名>[下标 ] .成员名

4.C++允许同类型的结构变量间的赋值!

5.#include
strcpy_s(结构变量名.结构体的内容,所赋的值)
或者
变量名.成员名=赋值

6.结构体之间仍然可以进行嵌套,一个结构体可以成为另一个结构体的成员之一。

联合(基本上等同于结构)

不同:
结构是异址(即结构成员各有自己的内存单元)
联合是共址(联合成员共用一个内存单元,该单元的大小等于联合中数据长度最长的相等)

union <联合名>
{
<联合成员的说明>
}<联合变量>;

注:由于联合成员是共址的,一般,在某一时刻联合变量的各个成员中只有一个是有效的,所以在给联合变量赋值的时候,同一时刻只能给联合变量中的某一个成员赋值

链表

struct student
{
结构体
}
(为了更加的方便修改和易于操作,在结构体内部减少定义指针,在单独的结点中去定义)

typedef student ElemType;
(将 student 都重命名为 ElemType )

struct Node
{
ElemType data;
Node*next;
}

Node*head,*p;
p=head;
p->data.(结构成员)

一、 单链表
链式存储结构: (数据元素的存放是不连续的)
一个数据元素占用两个存储单元
一个用来存放数据元素的值,另一个存放下一个数据元素存储单元的地址
(在类、结构体中等没有连续的存储单元的时候可以使用链表)
例如 :
struct Node
{
int num;
char name[20];
char sex;
double score;
student *next;
}

注:链表的实现基本上是以指针为基础进行的,尽量设有头指针,是整个代码的运行更加易读和简洁;

1.存储的元素本身的信息和指示器直接的后继元素存储位置的元素的信息,这两个信息组成一个元素的存储映像,称为结点
即: 数据域+指针域

2.头指针:指向链表中的头结点的指针!
注意:一般头结点是不去改变它的本身,这么做是为了后续的方便的操作!所以一般再重新定义一个指针p去遍历链表达到输出和遍历的目的!
(Head)
3.首元结点:单链表中存放第一个元素的结点

4.头结点:单链表中的第一个结点之前附设的一个结点,它的数据域不存放信息或存放如现行的长度等附加信息!

5.表结点:存放数据元素的结点
(大的概念)

单链表的基本运算

1.查找运算:

2.删除运算:

3.插入运算:

动态链表

使用指针去完成!
链表一般常与结构体联合使用,所以定义一个新的结构体时

*<结构体名>新的成员名=new 结构体名!
补充新的成员名的具体代码

优点:按需开辟内存单元

循环链表

定义:指链表中最后的那个链结点的指针域存放指向链表最前面那个结点的指针,整个链表形成了一个环

特点:只要给出了表中的任何一个结点的位置,则由此出发就可以访问表中的其他所有的结点。

多重链表

数据域+两个指针域
其中一个指向结点的直接前驱结点,另一个指向结点的直接后继结点。

形式 :
指向前驱结点的指针域 +数据域+ 指向后继结点的指针域;

屏幕的输出操作

注:
1.cin是istream类的对象,用来处理标准输入,即键盘输入
2.cout是ostream类的对象用来处理标准输出,即屏幕输出
3.cerr是ostream类的对象,用来处理标准出错信息,他提供不带缓冲区的输出
4.clog是ostream类的对象,用来处理标准出错信息,但是他提供带缓冲区的输出

输出函数
put() :将单个字符送到输出流之中
write(): 将字符串和读取的长度送到输出流之中

键盘输入:
cin 以空白符等作为分隔符进行输出!

C++中对文件的相关操作!

科普:
1.abort()函数
头文件:stdlib

功能: 异常终止一个进程。中止当前的过程,返回一个错误代码。
错误代码的缺省值是3

2.Ctrl+Z 代表输入流的结束!!
(先按回车键,再按Ctrl+Z)

3.快速添加注释: Ctrl+k+c (先按Ctrl+k再按Ctrl+c)
快速取消注释: Ctrl+k+u (先按Ctrl+k再按Ctrl+u)

文件大概的分类为:文本文件 和 二进制文件
文本文件使用 getline() 去读。
二进制文件使用 read()去读,write()函数去写

ofstream : 写操作
idstream: 读操作
fstream: 读写操作

(包含头文件 #include)

写文件

1.包含头文件

2.创建流对象:
ofstream ofs;

3.打开文件
ofs.open(“文件路径”,打开方式)
(当文件的路径是相对路径时,文件默认创建并写入和程序相同的目录下!!!)

注:当文件没有打开时,其值为0
当文件打开时,其值为非0

4.写数据
ofs<<“写入的数据”

5.ofs.close();

文件的打开方式:

ios::in 为读文件而打开文件
ios::out 为写文件而打开文件
ios::ate 初始位置:文件尾
ios::app 追加的方式写文件
ios::trunc 如果文件存在就先删除,在创建
ios::binary 二进制方式打开文件

注:文件的打开方式可以配合使用,使用 | 进行连接

读文件(文本文件)

1.包含头文件
2.创建流对象
ifstream ifs;

3.打开文件并判断文件是否打开成功

ifs.open(“文件路径”,打开方式)

4.读数据
四种方式读取

5.关闭文件
ifs.close();

	ifstream infile;
	const int N=100;
	//打开文件
	infile.open("E:/Test_out.txt", ios::in);
	//防错处理,判断文件是否真的打开了,未打开就直接退出
	if (!infile.is_open())
	{
		cout << "文件未能正常打开" << endl;
		return -1;
	}





	/*
	第一种读操作
	(输入流的读取)
	char buff[n] = {};

	//文件能够读取的操作
	while (infile >> buff)
	{
		cout << buff << endl;
		//输出buff的内容
	}

	infile.close();
	*/



	//读操作的第二种方法
	//(getline()方法的读取,这个一般是最常用的方法)
	
	char buff[N] = {0};
	while (infile.getline(buff, N))
	{
		cout << buff << endl;
	}

	infile.close();
	



	//读操作的第三种方法
	/*(常用的方法)
	(当读取的文件中包含中文字符时,一个汉字在UTF-8中是两个字节,当再使用char
	的相关类型去进行操作时就会出现乱码)
	
	string buff;
	while (getline(infile, buff))
	{
		cout << buff << endl;
	}

	infile.close();
	*/

gcount() :
函数gcount()被用于输入流,并返回上一次输入操作被读入的字符的数目(包括空白符)

peek():
从输入流中返回下一个字符,但是并不提取它,遇到流结束标志时返回 EOF !

get ():
读取单个字符

read():
读取一个字符串

getline(const char*p,读取的个数):
读取一个字符串,包括空白符

write():
输出一个字符串

put():
输出一个字符

eof(): 当文件结束时返回非0值,
当文件没有结束时,他返回0值!

你可能感兴趣的:(笔记,day,c++,c语言)