前言
c和c++是什么关系?
c++是对c的升级和完善
c有什么缺陷?
1.不严谨 char *p="hello";p='H' const int i;(没初始化)
2.名字冲突 作用域
3.c:面向过程,线性过程 c++:面向对象,封装起来的
4.无法解决大规模问题
为什么叫c++?
完善:new c
扩展: c with class
自增
c++学习方法
1.语法细节不建议钻牛角尖
char a[10]; [] () 3.14 double open("",O_CREAT) pthread)create
2.多做练习
3.看参考书
1.c++和c的差异
1.1第一个c++程序
#include<iostream>
#include <cstdio>
using namespace std;//加了之后,cout月endl 之前可也不写std
int main()
{
printf("hello world\n");
std::cout <<"hello world"<< '\n';
std::cout <<"hello world"<< std::endl;
return 0;
}
简化
using namespane std;//以下的 cout 与 cin 都默认为std域内的
1.2输入和输出
主要用于代码的调试
cout:输出流对象
自动匹配类型
cin :输入流对象
空格或者回车都可以区分
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a=100;
float f=3.14;
char ch='a';
double b=1.24;
string str ="hello";
char buf[10] = "world";
printf("%d %f %c %lf\n",a,f,ch,b);
//cout会自动匹配不同变量的数据类型
cout<< a << f << ch<< b<< str<<endl;//连在一起
cout<< a <<endl;
cout<< f <<endl;
cout<< ch <<endl;
cout<< b<<endl;
cout<< str <<endl;
cout<< buf <<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int a;
char ch;
float b;
double d;
string str;
cout << "please input:\n"<< endl;
# if 0
cin >> a;
cin >> ch;
cin >> b;
cin >> d;
cin >> str;
#endif
cin >> a >> ch >> b >> d >>str;
cout << a << " " << b << " " << d << " "
<< str << endl;
return 0;
}
1.3引用类型
1.c语言中是通过typedef给数据取别名
typedef int data_t;
2.c++新增,给变量取别名(reference)
int &b=a;
b与a的地址与值都一样注意:两个变量不能取同一个别名
3.引用传参
通过取别名来实现地址改变
fun(a,b);
void fun(int &x,int &y);//x== a,y== b,连地址都是一样的
更高效,不需要开辟新的空间,变量的地址是一样的
指针存在野指针,不安全,闯红灯行为,可能出世可能不出事,和指针相比,引用更安全
1.4内联函数
普通调用函数:
void fun(void)......
int n=0;
while(n<5)
{
fun();
n++;
}
缺陷:跳转10次
c++提供了一种提高效率的方法:内联函数
语法:inline 存储类型 数据类型 函数名(参数列表);(以空间换时间)
inline void fun(void)......
while(n<5)
{
fun();
n++;
}
//替换为
//cout<< "call fun " << endl;
//cout<< "call fun " << endl;
//cout<< "call fun " << endl;
//cout<< "call fun " << endl;
//cout<< "call fun " << endl;
注意:内联函数的限制:
使用内联函数可以节省运行时间,但却增加了目标程序的长度。(以空间换时间)
因此一般只将规模很小(一般为5个语句以下)而使用频繁的函数声明为内联函数。
由于多个源文件是分开编译的,要内联就应该把内联函数声明在头文件中。
内置函数中不能包括复杂的控制语句,如循环语句和switch语句
1.5函数重载
大规模代码,函数重名不可避免
函数重载:在同一个作用域下,函数名相同,参数不同(个数不同,类型不同,个数和类型都不同),返回值可相同可不相同。
#include <iostream>
using namespace std;
int add(int x)
{
return x+x;
}
int add(int x,int y)
{
return x+y;
}
float add(float x,float y)
{
return x+y;
}
double add(double x,double y)
{
return x+y;
}
int main()
{
cout << add(5) << endl;
cout << add(5,10) << endl;
return 0;
}
小数是double类型,要调用float类型需要处理
add(1.2f,2.4f);//说明数据是float类型
写一个double类型的函数
float a=1.2,b=2.4; add(a,b);//调用float类型的函数
默认参数;
1.默认参数,函数调用时可以不用传参
2.如果给某一参数设置了默认值,那么在参数表中,其后所有参数也必须设置默认值
3.如果进行了函数声明,只能在声明中设置默认值
#include <iostream>
using namespace std;
//只用给第一个赋值
int add(int x,int y=20,int z=30)
{
return x+y+z;
}
int main()
{
cout << add(1) << endl;
return 0;
}
多个重载函数都有默认参数时,出错
编译器不会帮你选择,只会报错
优先选择同类型的函数,没有时可以隐式转换的也可以用,int,double互相都可以转换
1.6作用域和名字空间
作用域
局部域:局部变量所在作用域
全局域:全局变量所在的作用域
名字空间域:管理函数 变量 类等;(大规模代码,之前已经用函数重载解决一部份问题,但是碰到函数名一样,参数也一样的情况,用名字空间域来解决重名)
用法:
namespace 名称 {
函数
变量
类
}
#include <iostream>
using namespace std;
namespace A
{
void fun()
{
cout << "call fun1" << endl;
}
}
namespace B
{
void fun()
{
cout << "call fun2" << endl;
}
}
int main()
{
A::fun();
B::fun();
using namespace A;//申明之后所有的fun都是名字空间域A的
fun();
B::fun();//依旧可以
}
:: 作用域访问符
::m 访问全局变量m
类域,每个类空间都定义了自己的域
1.7 new和delete
c:malloc和free
c++:new和delete
char *p =new char [1024];
strcpy(p,"hello world");
cout << p << endl;
delete []p;
//int *q=new int [1];
int *q=new int;//只开一个空间时,可以把中括号省略
*q=100;
cout << *q << endl;
//delete []q;
delete q;
1.8Type
c++有更严格的数据类型检查
1.不能将char * 给int *
2.不能用char * 指向const char *
3.函数返回值的类型,要一致
4.c++中的const是真的该碧聊,记得一定要赋初值(c语言中可以通过指针修改const修饰的局部变量)
5.强制类型转换
int i;
char ch;
ch=(char)i;//都对
ch=char (i);
1.9作业
学生成绩管理系统
输入学生信息(姓名,学号,成绩),可以根据学习学号输出学生信息,可以根据学生成绩输出学生信息。用c++实现
c++的头文件没有.h
gcc 1.c
g++ 2.cpp
ctrl n 新建文件
ctrl s 保存
f11 编译并运行
ctrl c 关闭终端
#include <iostream>
#include <iomanip>
#include <string.h>
using namespace std;
typedef struct stu
{
char name[64];
int id;
float score;
}Stu;
Stu info[20]={"张三",1,85.6,"李四",2,67.6};
int top=1;
void find()
{
int x;
cout <<"1.通过姓名查找\n" << endl;
cout <<"2.通过学号查找\n" << endl;
cout <<"3.通过成绩查找\n" << endl;
cin >> x;
if(x==1)//姓名
{
int i;
char name[64];
cout << "请输入姓名" << endl;
cin >> name;
for(i=0;i<top+1;i++)
{
if(strcmp(info[i].name,name)==0)
{
cout << setw(12) << info[i].name << setw(3) << info[i].id <<
setw(6) << info[i].score << endl<<endl;
}
}
}
else if(x==2)//学号
{
int i;
int id;
cout << "请输入学号" << endl;
cin >> id;
for(i=0;i<top+1;i++)
{
if(info[i].id==id)
{
cout << setw(12) << info[i].name << setw(3) << info[i].id <<
setw(6) << info[i].score << endl;
}
}
}
else if(x==3)//成绩
{
int i;
float score;
cout << "请输入成绩" << endl;
cin >> score;
for(i=0;i<top+1;i++)
{
if(info[i].score==score)
{
cout << setw(12) << info[i].name << setw(3) << info[i].id <<
setw(6) << info[i].score << endl;
}
}
}
cout << "查询结束\n" << endl;
}
void insert()//引用传参
{
cout << "请输入姓名,学号,成绩\n" << endl;
top++;
cin >>info[top].name >> info[top].id >> info[top].score;
cout << "输出完毕" << endl << endl;
}
int main()
{
int x;
while(1)
{
cout <<"欢迎进入学生成绩系统\n" << endl;
cout <<"1.查询成绩\n" << endl;
cout <<"2.插入信息\n" << endl;
cout <<"0.退出\n" << endl;
cout << "请输入0~2\n" << endl;
cin >> x ;
switch(x)
{
case 1:find();break;
case 2:insert();break;
case 0:goto loop;
default: cout << "错误输入,请重新输入" << endl;
}
}
loop:
cout << "感谢您的使用,再见\n" << endl;
return 0;
}