【万字长文】关于C++ Primer Plus(一)


这篇笔记是小鱼在上学时候看《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.08.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-6
3.45/1000000

浮点常量:
3.45E6ffloat类型
3.45E6L
long 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;
}

本次笔记就做到这里吧,希望能帮到大家!
如果学习不太忙的话,下面的笔记会继续补上滴!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值