c++
1.1 学习说明_【C++工程师面试宝典】学习说明_互联网校招面试真题面经汇总牛客网牛客网
https://www.nowcoder.com/tutorial/93/8ba2828006dd42879f3a9029eabde9f1
microsoft/STL: MSVC's implementation of the C++ Standard Library.
https://github.com/microsoft/STL
C++ 的「标准库」 和「STL 标准模板库」,它俩有很多相同的内容,所以常有人误认为 STL 是整个 C++ 标准库,但它俩都不是彼此的超集。
C++ 标准库有多种实现,微软只是其中一家。
链接:https://github.com/microsoft/STL
目前该仓库包含所有的产品源代码、一个新的 cmake 构建系统等。
协议:Apache License v2.0 with LLVM Exceptions
选择这许可证是方便 libc++ 项目与 MSVC 的 STL 共享代码,不过目前两个项目没有合并,仍然是支持不同平台的不同库,有着不同的数据结构表示。
C++函数式编程(二)纯函数_Popy007(Twinsen)的专栏-CSDN博客_c 纯函数
https://blog.csdn.net/popy007/article/details/8508776
demo
//hello world
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World";
return 0;
}
c++ qa
1.代码报错 warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] - 神様のいない日々 - CSDN博客
https://blog.csdn.net/VVVLeHr/article/details/86697346
warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] - zkfopen - 博客园
https://www.cnblogs.com/zkfopen/p/10521715.html
在C++11中有明确规定
char* p = "abc"; // valid in C, invalid in C++
如果你进行了这样的赋值,那么编译器就会跳出诸如标题的警告。但是如果你改成下面这样就会通过warning
char* p = (char*)"abc"; //OK
或者这样:
char const *p="abc";//OK
这到底是怎么一回事呢?事实上,我们在学习c或者c++的时候都知道,如果在赋值操作的时候,等号两边的变量类型不一样,那么编译器会进行一种叫做 implicit conversion
的操作来使得变量可以被赋值。
在我们上面的表达式中就存在这样的一个问题,等号右边的"abc"
是一个不变常量,在c++中叫做string literal
,type
是const char *
,而p
则是一个char
指针。如果强行赋值会发生什么呢?没错,就是将右边的常量强制类型转换成一个指针,结果就是我们在修改一个const
常量。编译运行的结果会因编译器和操作系统共同决定,有的编译器会通过,有的会抛异常,就算过了也可能因为操作系统的敏感性而被杀掉。
像这种直接将string literal
赋值给指针的操作被开发者们认为是deprecated
,只不过由于以前很多代码都有这种习惯,为了兼容,就保留下来了。
operation record
基本输入输出
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
//输出文字
cout << "请输入一个数a\n";
int a;
//获取输入内容
cin>>a;
/*输出文字*/
cout << "请输入另一个数b\n";
int b;
/*获取输入内容*/
cin>>b;
cout<<"a+b="<<a+b<<"\n";
char c;
cin>>c;
return 0;
}
code 1
demo 1
/*教材第一章中复数的实现*/
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
//typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
/*定义复数的结构*/
typedef struct
{
float Realpart;
float Imagpart;
}Complex;
/*构造或者说产生一个复数*/
void Create(Complex &C,float x,float y)
{
C.Realpart=x;
C.Imagpart=y;
}
/*取复数的实部*/
float GetReal(Complex C)
{
return C.Realpart;
}
/*取复数的虚部*/
float GetImag(Complex C)
{
return C.Imagpart;
}
/*输出一个复数*/
void Disp(Complex C)
{
cout<<GetReal(C)<<"+i"<<GetImag(C)<<"\n\n";
//return;
}
/*求两个复数之和*/
Complex Add(Complex C1,Complex C2)
{
Complex sum;
sum.Realpart=C1.Realpart+C2.Realpart;
sum.Imagpart=C1.Imagpart+C2.Imagpart;
return sum;
}
/*求两个复数之差*/
Complex Sub(Complex C1,Complex C2)
{
Complex difference;
difference.Realpart=C1.Realpart-C2.Realpart;
difference.Imagpart=C1.Imagpart-C2.Imagpart;
return difference;
}
int main(int argc, char *argv[])
{
Complex C,C1,C2;
float x1=0.00;
float y1=0.00;
float x2=0.00;
float y2=0.00;
float a=0.00;
float b=0.00;
int choose;
cout<<"对复数的操作\n";
cout<<"1. 建立一个复数\n";
cout<<"2. 取复数的实部\n";
cout<<"3. 取复数的虚部\n";
cout<<"4. 输出一个复数\n";
cout<<"5. 求两个复数之和\n";
cout<<"6. 求两个复数之差\n";
cout<<"0. 退出\n\n";
choose=-1;
while(choose!=0)
{
cout<<"请选择:";
cin>>choose;
switch(choose)
{
case 1:
cout<<"请输入复数的实部:";
cin>>a;
cout<<"请输入复数的虚部:";
cin>>b;
Create(C,a,b);
Disp(C);
break;
case 2:
cout<<"复数的实部是:"<<GetReal(C)<<"\n\n";
break;
case 3:
cout<<"复数的虚部是:"<<GetImag(C)<<"\n\n";
break;
case 4:
//Create(C,a,b);
Disp(C);
break;
case 5:
cout<<"请输入第一个复数的实部:";
cin>>x1;
cout<<"请输入第一个复数的虚部:";
cin>>y1;
Create(C1,x1,y1);
cout<<"请输入第二个复数的实部:";
cin>>x2;
cout<<"请输入第二个复数的虚部:";
cin>>y2;
Create(C2,x2,y2);
C=Add(C1,C2);
cout<<"两个复数之和是:";
Disp(C);
break;
case 6:
cout<<"请输入第一个复数的实部:";
cin>>x1;
cout<<"请输入第一个复数的虚部:";
cin>>y1;
Create(C1,x1,y1);
cout<<"请输入第二个复数的实部:";
cin>>x2;
cout<<"请输入第二个复数的虚部:";
cin>>y2;
Create(C2,x2,y2);
C=Sub(C1,C2);
cout<<"两个复数之差是:";
Disp(C);
break;
}
}
return 0;
}
demo 2
/*教材2.2节中算法2.1到算法2.4的实现*/
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
#define MAXSIZE 100 //顺序表可能达到的最大长度
typedef struct{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList;
Status InitList_Sq(SqList &L){ //算法2.1 顺序表的初始化
//构造一个空的顺序表L
L.elem=new ElemType[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem) exit(OVERFLOW); //存储分配失败
L.length=0; //空表长度为0
return OK;
}
int LocateElem_Sq(SqList L,ElemType e){ //算法2.2 顺序表的查找
//顺序表的查找
for(int i=0;i<L.length;i++)
if(L.elem[i]==e) return i+1;
return 0;
}
Status ListInsert_Sq(SqList &L,int i,ElemType e){ //算法2.3 顺序表的插入
//在顺序表L中第i个位置之前插入新的元素e
//i值的合法范围是1<=i<=L.length+1
if(i<1 || i>L.length+1) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(int j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
++L.length; //表长增1
return OK;
}
Status ListDelete_Sq(SqList &L,int i,ElemType &e){ //算法2.4 顺序表的删除
//在顺序表L中删除第i个元素,并用e返回其值
//i值的合法范围是1<=i<=L.length
if(i<1 || i>L.length) return ERROR; //i值不合法
e=L.elem[i-1]; //将欲删除的元素保留在e中
for(int j=i;j<=L.length;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
--L.length; //表长减1
return OK;
}
int main()
{
SqList L;
int i,res,temp,a,b,c,e,choose;
cout<<"顺序表操作\n";
cout<<"1. 建立顺序表\n";
cout<<"2. 输入数据\n";
cout<<"3. 查找\n";
cout<<"4. 插入\n";
cout<<"5. 删除\n";
cout<<"6. 输出数据\n";
cout<<"0. 退出\n\n";
choose=-1;
while(choose!=0)
{
cout<<"请选择:";
cin>>choose;
switch(choose)
{
case 1:
if(InitList_Sq(L)) //创建顺序表
cout<<"成功建立顺序表\n\n";
else
cout<<"顺序表建立失败\n\n";
break;
case 2: //输入10个数
cout<<"请输入10个数:\n";
for(i=0;i<10;i++)
cin>>L.elem[i];
L.length=10;
cout<<endl;
break;
case 3: //顺序表的查找
cout<<"请输入所要查找的数:";
cin>>e; //输入e,代表所要查找的数值
temp=LocateElem_Sq(L,e);
if(temp!=0)
cout<<e<<" 是第 "<<temp<<"个数.\n\n";
else
cout<<"查找失败!没有这样的数\n\n";
break;
case 4: //顺序表的插入
cout<<"请输入两个数,分别代表插入的位置和插入数值:";
cin>>a>>b; //输入a和b,a代表插入的位置,b代表插入的数值
if(ListInsert_Sq(L,a,b))
cout<<"插入成功.\n\n";
else
cout<<"I插入失败.\n\n";
break;
case 5: //顺序表的删除
cout<<"请输入所要插入的数:";
cin>>c; //输入c,代表要删除数的位置
if(ListDelete_Sq(L,c,res))
cout<<"删除成功.\n被删除的数是:"<<res<<endl<<endl;
else
cout<<"删除失败.\n\n";
break;
case 6: //顺序表的输出
cout<<"当前顺序表为:\n";
for(i=0;i<L.length;i++)
cout<<L.elem[i]<<" ";
cout<<endl<<endl;
break;
}
}
return 0;
}
/*教材2.3.4节中双向链表算法2.12到算法2.13的实现*/
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
typedef struct DuLNode
{
ElemType data; //结点的数据域
struct DuLNode *prior;
struct DuLNode *next; //结点的指针域
}DuLNode,*DuLinkList; //DuLinkList为指向结构体DuLNode的指针类型
Status InitDuList_L(DuLinkList &L){
//构造一个空的双向链表L
L=new DuLNode; //生成新结点作为头结点,用头指针L指向头结点
L->next=NULL; //头结点的指针域置空
L->prior=NULL;
return OK;
}
DuLNode *GetElemP_DuL(DuLinkList L,int i){
//在带头结点的双向链表L中查找第i个元素,返回结点的地址
int j;
DuLNode *p;
p=L->next;j=1; //初始化,p指向第一个结点,j为计数器
while(j<i&&p){ //顺链域向后扫描,直到p指向第i个元素或p为空
p=p->next;++j;
}
if(!p || j>i) return NULL; //第i个元素不存在
return p;
} //GetElemP_DuL
Status ListInsert_DuL(DuLinkList &L,int i,ElemType e){ //算法2.12 双向链表的插入
//在带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长+1
DuLNode *s,*p;
if(!(p=GetElemP_DuL(L,i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
s=new DuLNode; //生成新结点s
s->data=e; //将结点s数据置为e
s->prior=p->prior; //将结点s插入L中,需要修改4个指针域
p->prior->next=s;
s->next=p;
p->prior=s;
return OK;
} //ListInsert_DuL
Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e){ //算法2.13 双向链表的删除
//删除带头结点的双向链表L中第i个位置之前插入元素e,i的合法值为1<=i<=表长
DuLNode *p;
if(!(p=GetElemP_DuL(L,i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
e=p->data; //保存被删结点的数据域
p->prior->next=p->next; //修改被删结点的前驱结点的后继指针
p->next->prior=p->prior; //修改被删结点的后继结点的前驱指针
delete p; //释放被删结点的空间
return OK;
} //ListDelete_DuL
void CreateDuList_L(DuLinkList &L,int n){
//后插法正位序输入n个元素的值,建立带表头结点的双向链表L,同时建立前驱指针
DuLNode *r,*p;
L=new DuLNode;
L->next=NULL; //先建立一个带头结点的空链表
r=L;
cout<<"请输入"<<n<<"个数\n"; //尾指针r指向头结点
for(int i=0;i<n;i++){
p=new DuLNode; //生成新结点
cin>>p->data; //输入元素值
p->next=NULL;r->next=p; //插入到表尾
r=p; //r指向新的尾结点
p->prior=L->prior; //插入到表头
L->prior=p;
}
} //CreateDuList_L
int main()
{
int res,a,b,choose;
DuLNode *L,*p;
cout<<"双向链表操作\n";
cout<<"1. 建立双向链表\n";
cout<<"2. 输入数据\n";
cout<<"3. 双向链表的插入\n";
cout<<"4. 双向链表的删除\n";
cout<<"5. 输出数据\n";
cout<<"0. 退出\n\n";
choose=-1;
while(choose!=0)
{
cout<<"请选择:";
cin>>choose;
switch(choose)
{
case 1: //建立一个双向链表
if(InitDuList_L(L))
cout<<"成功建立双向链表!\n";
break;
case 2: //使用后插法创建双向链表
CreateDuList_L(L,10);
break;
case 3: //双向链表的插入
cout<<"请输入两个数分别代表插入的位置和数值:";
cin>>a>>b;
if(ListInsert_DuL(L,a,b))
cout<<"成功在"<<a<<"位置插入"<<b<<endl;
else
cout<<"插入失败!\n";
break;
case 4: //双向链表的删除
cout<<"请输入一个位置用来删除:";
cin>>a;
if(ListDelete_DuL(L,a,res))
cout<<"删除成功!被删除的数是"<<res<<endl;
else
cout<<"删除失败!\n";
break;
case 5: //双向链表的输出
cout<<"现在的链表是:\n";
p=L->next;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
break;
}
}
return 0;
}
发表评论