这篇笔记是小鱼在上学时候看《C++ Primer Plus》时所作,里面都是知识点的总结和归纳,希望能帮上大家!
预处理器编译指令:#include
编译指令:using namespace
函数头:
int main( ) (描述了函数与调用它的函数之间的接口)
函数名前面的是部分叫函数返回类型 (int main()的函数返回类型是int,描述的是从函数返回给调用它的函数信息)
函数名后括号中的部分叫做形参列表(参数列表) (它描述了从调用函数传递给被调用的函数的信息)
main()——>(空括号表示main()函数不接受任何信息或者不接受任何参数)
int main()或int main(void)标准形式
void main()不是标准形式
return 0只适合main()函数
头文件名:
iostream类似文件叫做包含文件(include file)或者头文件(header file)
名称空间:
定义一个命名空间,解决变量和函数的命名冲突问题 namespace name{ ...... }
例:
namespace li{
fp=1;
}
namespace pi{
fp=1;
}
命名空间内部不仅可以声明或定义变量,对于其它能在命名空间以外声明或定义的名称,同样也都能在命名空间内部进行声明或定义,例如类、函数、typedef、#define 等都可以出现在命名空间中。
使用命名空间的方法:
1.域解析操作符::
指明使用的命名空间:
li::fp=1;
2.using声明(可以针对命名空间中的一个变量,也可以用于声明整个命名空间)
using namespace li;
fp=1;
函数:
double sqrt(double);
=double x; x=sqrt(......)
运用sqrt可以输入头文件cmath
pow函数:
可接受两个参数,返回值以第一个参数为底,第二个参数为指数的幂
例:5的8次方
double pow(5.0,8.0);
C++命名规则:
- ·在名称中只能使用字母字符、数字和下划线
- 名称的第一个字符不能是数字
- 区分大小写字符与小写字符
- 不能将C++关键字用作名称
- 以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,作用全局标识符。
- C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制
C++的基本整形:(宽度递增)
char
short
int
long
long long
C++确保了整形的最小长度:
- short至少16位
- int至少和short一样长
- long至少32位,且至少与int一样长
- long long至少64位,且至少和long一样长
位与字节:
计算机的内存基本单元是位bit
字节通常指的是8位的基本单元,描述了计算机内存量的度量单位,1KB=1024字节
头文件climits:
定义了符号常量来表示类型的限定
climits中符号常量
CHAR_BIT–>char的位数
CHAR_MAX–>char的最大值
CHAR_MIN–>char的最小值
SCHAR_MAX–>signed char的最大值
SCHAR_MIN–>signed char的最小值
UCHAR_MAX–>unsigned char的最大值
…
运算符sizeof:
sizeof(int)
在8位字节的系统中,int的长度位4个字节
bool型:
1==>正确true
0==>错误false
int ans=true == ans=1
int promise=false == promise=0
bool任何数字值或者指针值都可以被隐式转换:
bool start=-100 == true
bool stop=0 == false
const限定符:
const int Months=12(限定声明了Months为常量=12)
创建常量的通用格式为 const type name=value(声明常量时要赋值)
浮点型:
float有效位数只有六位
E表示法:
3.45E63450000
3.45E-63.45/1000000
浮点常量:
3.45E6ffloat类型
3.45E6Llong double类型
算术运算符:
/:取整数部分,小数舍去(17/5=3)
%:取余数(17%5=2)
%和/的实际运用:
可用作计算英石和余下多少磅
const int Lbs_per_stn=14;
int lbs;
cout<<"......"<<endl;
int stone=lbs/Lbs_per_stn;
int pounds=lbs%Lbs_per_stn;
类型转换——潜在的数值转换问题:
- 将较大的浮点数类型转换为较小的浮点数类型:double–>float
问题:精度降低,只可能超出目标类型的取值范围,结果将不确定
- 将浮点型转换为整型:float–>int
问题:小数部分丢失,原来的值可能超出目标类型的取值范围,在这种情况下,结果将不确定
- 将较大的整型转换为较小的整型:long–>short
问题:原来的值可能超出目标类型的取值范围,通常只复制右边的字节
- 将0赋给bool变量时,将被转换为false;非零值将被转换true
- 将浮点型转换成整形时,将采取丢弃小数部分
类型转换
例:
A=19.99+11.99=31
B=(int)19.99+(int)11.99=30
C=int(19.99)+int(11.99)=30
auto声明:
作用:推断变量的类型
用法:auto x=100
C++中的整形(从小到大):
bool、char、signed chat、unsigned char、short、unsigned short、int、unsigned int、long、unsigned long、long long、unsigned long long
C++中浮点型(从小到大):
float、double、long double
数组:
声明需指出:
- 存储在每个元素中的值的类型
- 数组名
- 数组中的元素数
例:创建一个名为months的数组,该数组有12个元素,每个元素都可以存储一个short类型的值:
short months[12];
声明数组的通用格式:
topeName arrayName[arraySize];
其中,arraySize必须为整型常数或者const的值,也可以是常量表达式(8*sizopf(int))
可以存在特定的数组类型,如char数组和long数组
例:
float loans[20]; //float数组
C++中列表初始化新增功能:
- 初始化数组可省略等号(=):
double earnings[4] {1,2,3,4};
- 可不在大括号内包含任何东西,这将把所有元素都设置为零
unsigned int counts[10]={};
- 列表初始化禁止缩窄转换
char tlifs[4]={'h','i',112,'\0'};//112在char变量里面
字符串:
存储在内存的连续字节中的一系列字符
C-风格的字符串具有一种特殊的性质:以空字符结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾
char cat[3]={'b','c','\0'};
字符串常量(字符串字面值)表示法:
char cat[3]="bc";
strlen()函数:
返回存储在数组中的字符串的长度(只计算可见的字符),数组长度不能少于strlen()+1
面向行的输入:getline():
读取整行,通过回车键输入的换行符来确定输入结尾(不保存换行符)
函数调用:
cin.getline(name,20);//(数组名称,元素数量)
程序设计:
#include<iostream>
using namespace std;
int main(){
const int ArSize=20;
char name[ArSize];
char dessert[ArSize];
cout<<"Enten your name:\n";
cin.getline(name,ArSize);
cout<<"Enten your favorite dessert:\n";
cin.getline(dessert,ArSize);
cout<<"I have some delicious"<<dessert;
cout<<"for you,"<<name<<".\n";
return 0;
}
面向行的输入——get():
与getline()相似,但将换行符留在队列中
假设调用两次get():
cin.get(name,ArSize);
cin.get(dessert,ArSize);
由于第一次调用后,换行符将留在队列中,因此第二次调用时看到的第一个字符便是换行符,于是get()认为已到达行尾,没发现任何读取的内容
可采用的调用方式:
cin.get(name,ArSize);
cin.get();
cin.get(dessert,ArSize);
另一种方法:
cin.get(name,ArSize).get();
使用get()方法将两个类成员函数拼接起来
string类:(比数组用法更简单)
赋值:统计字符串str中字符的个数,不包括’\0’
string str1="1";
拼接:
string str1="1";
string str2="3";
//str1+str3="13";
利用头文件cstring,可以使用strcpy()和strcat()函数对数组进行操作:
strcpy()函数:
将字符串复制到数组中
strcpy(charr1,charr2);
strcat()函数:
将字符串附加到数组末尾
strcat(charr1,charr2);
具体用法:
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char charr1[20];//创建一个空数组
char charr2[]="123321";//创建一个初始化数组
string str1;//创建str1类
string str2="456654";创建str2类并赋予字符串“456654”
str1=str2;//str2类中的字符串交给str1
strcpy(charr1,char2);//将数组charr2中的字符串复制给charr1
str1+=" 789";//str1类的拼接
strcat(charr1,"789");//数组的拼接,将“789”拼接到charr1数组的末尾
int len1=str1.size();//计算str1类的字符串长度
int len2=strlen(charr1)//计算charr1数组的字符串长度
}
其中strlen()函数的作用是:统计字符串str中字符的个数,不包括’\0’
结构介绍:
例如,公司需要建立一种类型描述其生产线上的充气产品成员。满足要求的结构建立:
struct inflatable{
char name[20];
float volume;
double price;
};
关键字struct表明定义了一个结构布局
标识符inflatable是这种数据格式的名称
大括号包含的是结构存储的数据类型的列表,其中每个列表都是一条声明
末尾 };为结构结束声明
定义了结构后,便可以创建这种类型的变量:
inflatable hat;
inflatable woopie_cushion;
inflatable mainframe;
(C++允许声明结构变量时省略关键字struct)
由于hat类型为inflatable,因此可以 使用成员运算符(.)来访问各个成员
例:
hat.volume:结构的volume成员
初始化结构:
#include<iostream>
using namespace std;
struct inflatable{//结构建立
char name[20];//创建存储名称的数组
float volume;//创建浮点型volume
double price;//创建浮点型价格类
};
int main(){
inflatable guest={
"Glorious Gloria",
1.88,
29.99
};
inflatable pal={
"Audacious Arthur",
3.12,
32.99
};
cout<<"Expand your guest list with"<<guest.name<<" and"<<pal.mame<<"!\n";
cout<<"you can hace both for $"<<guest.price+pal.parce<<"!\n";
}
利用赋值运算符将结构赋给令一个个同类型的结构
#include<iostream>
using namespace std;
strucr inflatable{
char name[20];
float volume;
double price;
};
int main(){
inflatable bouquet={
"sunflowers",
0.20,
12.49
};
inflatable choice;
cout<<"bouquet:"<<bouquet.name<<" for$"<<bouquet.price<<endl;
choice=bouquet;//赋值运算
cout......
}
结构数组:
创建一个包含100个inflatable结构的数组:
inflatable gifts[100];
其中每个元素都是inflatable的对象,可以与成员运算一起使用:
cin>>gifts[0].volume;
cout<<gifts[99].price<<endl;
共用体:
union 共用体名称{
成员列表
};
结构体和共用体的区别在于:
结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员
占用的内存:
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉
以data 为例,各个成员在内存中的分布如下:
成员 n、ch、m 在内存中“对齐”到一头,对 ch 赋值修改的是前一个字节,对 m 赋值修改的是前两个字节,对 n 赋值修改的是全部字节。也就是说,ch、m 会影响到 n 的一部分数据,而 n 会影响
共用体作用之一:
当数据项使用两种或者多种格式时(不同时使用),可节省空间
例:
struct inflatable{
char name[];
int type;
union id{
long id_num;
char id_num[20];;
} id_val;
};
...
inflatable prize;
...
if(prize.type==1)
cin>>prize.id_val.id_num;
else
cin>>prize.id_val.id_char;
匿名共用体:没有名称,其成员将成为位于相同地址处的变量
struct widger{
char brand[20];
int type;
union{
long id_num;
char id_char[20];
};
};
...
widger prize;
...
if...
由于共用体匿名,因此id_num,id_char被视为prize两个成员,地址相同,不需要中间标识符id.val
枚举:enum
enum spectrum{red,orang,yellow green,blue} //对应的整数值0~5
设置枚举量的值:
enum bits{one=1,two=2,four=4};//指定的数一定是整数
enum bigstep{first,second=100,third};//first=0,third=101
enum {zero,null=0,one,numero=1};//zero=null=0,one=numero=1
指针:
用&操作符可以获取变量的地址,指针变量用于存储地址
int *a;
const int b=1;
a=&b;
间接引用指针:
可获取由该指针指向的变量内容
int *a;
const int b=1;
a=&b;
cout<<*a;
-->a=1
- 放在可执行语句中的指针之前,称为间接引用操作符(cout<<*a)
- 放在指针定义之中时,成为指针定义符(int *a)
指针变量的地址:
int a=18
int *b=&a;
*b=40;
cout<<&b<<endl;//&b为指针的地址
指针的地址相当于二级指针
指针的初始化:
指针变量初始化的值是该指针类型的地址值
int a=1;
int *b=&a;//C++为指针分配一个指针空间,并用b的地址值初始化
指针运算:
int iArrat[10];
int sum=0;
int *iPtr=iArray;创建指针iPtr储存iArray的地址
for(int i=0;i<10;i++){//给数组赋值
iArray[i]=i*2;
for(int index=0;index<10;index++){//计算数组元素之和
sum+=*iPrt++;//(sum+=*iPrt;iPrt++;)由于iPrt是整形指针,iPrt++使指针指向下一个整型数
}
cout<<sum;
}
指针与数组:
int a[100];
int *iPrt=a;
第i个元素:
a[i]==*(a+i)==iPrt[i]==*(iPrt+i)
因为a+i表示第i个元素的地址,对第i个元素取值==*(a+i)
数组的求和运算的五种方法:
#include<iostream>
using namespace std;
int sum1,sum2,sum3,sum4,sum5;//全局变量
int iArray[]={1,4,2,7,13,32,21,48,16,30};//创建数组iArray
int *iPrt;//创建指针iPrt
int main(){
int size,n;
size=sizeof(iArray)/sizeof(*iArray);//元素个数,sizeof(*iArray)表示数组元素类型所占的字节数(可表示为sizeof(int))
for(n=0;n<size;n++){
sum1+=iArray[n];//数组相加
}
iPrt=iArray;//
for(n=0;n<size;n++){
sum2+=*iPrt++;//间接引用,输出数组地址中的值再相加
}
iPrt=iArray;
for(n=0;n<size;n++){
sum3+=*(iPrt+n);//间接引用
}
iPrt=iArray;
for(n=0;n<size;n++){
sum4+=iPrt[n];
}
iPrt=iArray;
for(n=0;n<size;n++){
sum5+=*(iArray+n);间接引用
}
}
堆:
堆允许程序在运行时,申请某个大小的内存空间
获取堆内存(动态内存):
利用malloc()函数获取,头文件alloc.h
void *malloc(size_t size);//size_t==unsigned long
该函数将从堆内存中切下一块size大小的内存,将指向该内存的地址返回,该内存的内容是位置的
例:从堆中获取一个整数数组,复制并打印
#include<iostream>
#include<alloc.h>
using namespace std;
int main(){
int arraysize;
int *array;
cout<<"请输入:"<<endl;
cin>>arraysize;
array=(int *)malloc(arraysize *sizeof(int));//申请大小为arraysize*sizeof(int)的堆内存
for(int count=0;count<arraysize;count++){
array[count]=count*2;
}
for(count=0;count<arraysize;count++){
cout<<array[count]<<" ";
}
cout<<endl;
}
调用malloc()函数更加完善的代码:
if(array=(int *)malloc(arraysize *sizeof(int))==NULL){//判断堆内存大小是否满足
cout<<"can't allocate more memory,terminating"<<endl;
exit(1);//结束程序
}
释放 堆内存:
void free(void*);
例:
#include<iostream>
#include<alloc.h>
using namespace std;
int main(){
int arraysize;
int *array;
cout<<"请输入:"<<endl;
cin>>arraysize;
if(array=(int *)malloc(arraysize *sizeof(int))==NULL){//判断堆内存大小是否满足
cout<<"can't allocate more memory,terminating"<<endl;
exit(1);//结束程序
}
for(int count=0;count<arraysize;count++){
array[count]=count*2;
}
for(count=0;count<arraysize;count++){
cout<<array[count]<<" ";
}
cout<<endl;
free(array);//释放堆内存
}
new与delete:
new类似于malloc(),操作数为数据类型,可以带初始化值表或单元个数,返回一个具有操作数之数据类型的指针
delete类似于free(),delete操作数是new返回的指针
例:
#include<iostream>
#include<alloc.h>
using namespace std;
int main(){
int arraysize;
int *array;
cout<<"请输入:"<<endl;
cin>>arraysize;
if((array=new int[ayyaysize])==NULL){//分配堆内存
cout<<"can't allocate more memory,terminating"<<endl;
exit(1);//结束程序
}
for(int count=0;count<arraysize;count++){
array[count]=count*2;
}
for(count=0;count<arraysize;count++){
cout<<array[count]<<" ";
}
cout<<endl;
delete[]array;//释放堆内存
}
const指针:
定义指向常量的指针只限制指针的间接访问操作,而不能规定指针指向的值的本身的操作规定性
例:将两个大小相等的数组传递给一个函数,让其完成复制字符串的工作,为了防止作为源数据的数组破坏,用常量字符串
#include<iosteram>
void mystrcpy(char *dest,const char *source){
while(*dest++=*source++);//空循环
}
int main(){
char a[20]="how are you";
char b[20];
mystrcpy(a,b);
cout<<b<<endl;
}
本次笔记就做到这里吧,希望能帮到大家!
如果学习不太忙的话,下面的笔记会继续补上滴!