马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 代号3 于 2018-4-30 15:13 编辑
423笔记
c: 面向进程 尽可能高效 代码复用率不高
c++: 面向对象 追求简洁
面向进程
函数最小单位 底层编程
面向对象
最小单位是类 打包 集中调用 互为联系 大型项目组织 语句 基本组成
面向对象的编程语言
完全全新的面向对象编程语言
eg: Object-c java c# 语法类同c python
传统语言的面向对象拓展 混合型语言
eg:c++
c 贝尔实验室为DEC公司开发PDP系列计算机操作系统时研制的 c作为unix操作系统的开发语言而广为应用
c独有特点
访问内存地址 寄存器 进行位操作 具有汇编语言功能
生成目标代码质量搞 程序运行效率高
c++是c的拓展 c是c++中的子集 c++包括c的全部特征 属性和优点 同时增加了对面向对象编程的完全支持
c++实现了类的封装 数据隐藏 继承及多态 使其代码可重用并容易维护
七个细节
1·const类型
2·内联函数
3·内存申请和释放
4·函数重载 名称粉碎/名字改编机制
5·函数默认参数
6·引用
7·c++输入输出
命名空间
const限定符
c的const限定符含义为一个不能改变值的变量
c++的const限定符的含义为一个有类型描述的常量 类比宏的用法(指针不可以改变 数值替换为宏 不可以修改内存-宏)
const一般不修饰常量修饰指针量
指针变量自身内存(4字节) 变量名
指针指向的内存 *变量名
const
const修饰 在*左边时 指针指向的内存为const eg:const char * pStr 指向内容不修改
const修饰 在*运算符右边的时候 指针变量的自身为const eg: char* const pStr
不能再保存其他变量 ??相当于一个常量保存区域
进行修改时不会报错
多应用在函数上
如果一个函数的形参是指针 应将其定义为const*类型 当函数内部需要修改指针指针指向的内容的时才考虑将
const去掉
数据安全 确保参数不随意改变
define
尽量少用define
宏是没有类型检查的 函数传参的时候容易将参数传错
定义常量 常用 const和enum来代替
const在编译的时候分配内存
difine 在预编译的时候进行替换 不分配内存
作用域不同
const定义的常变量作用域为该变量的作用域
difine 全程序引用
内联函数
使用内联函数代替有参宏
和宏一样实现替换功能 内联函数会检测参数类型
语法
inline 函数名(参数列表)
{
函数体;
}
直接将函数体代码放置到调用位置 减少代码开销
c++规定 inline关键字必须和函数体定义放在一起才可以实现内联 只放在函数声明前无用
只是对编译器的一种提示 而不是命令 大多数编译器拒绝内联(复杂函数例如循环 递归函数)
编译器会自动选择
new与delete
c malloc free在堆空间中开辟释放内存
c++ new delete 在堆空间中开辟 释放内存
new特点
返回值
自动匹配 兼容类型 不需要强制类型转换
int *pBuf =new int [15] 分配15个int型空间 60字节 ?是否申请了内存
int *pBuf =new int(15) 分配一个int型空间 4字节 ()内的值表示初始值
圆括号()初始化 中括号[] 申请多个
new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针)
new int(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址
new char[10];//开辟一个存放字符数组(包括10个元素)的空间,返回首元素的地址
new int[5][4];//开辟一个存放二维整型数组(大小为5*4)的空间,返回首元素的地址
float *p=new float (3.14159);//开辟一个存放单精度数的空间,并指定该实数的初值为//3.14159,
将返回的该空间的地址赋给指针变量p
new运算符使用的一般格式为 new 类型 [初值]
用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,
则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否成功。
c:
结构体申请
PERSON * pObj=(PERSON*)malloc(sizeof(PERSON))
申请多个
PERSON*pObj=(PERSON*)malloc(sizeof(PERSON)*10)
释放
free(pObj2)
c++:
申请结构体
PERSON* pObj2 =new char
申请多个
pObj=new PERSON [10]
释放
delete[] pObj2;[]内不需要加任何数值
int *pBuf =new int (15) 分配一个一个int型空间 不初始化
初始化语法
char *pArr =new char[5]{"1234"};
printf("%s\n",pArr); ?类比数组输出还是指针输出// 数组
delete[]pArr;
函数重载(函数重名)overload 函数的多态性
前提:相同作用域
构成重载方式 ?必有一个不同 可否多个//可多个
形参数量不同
形参类型不同
形参顺序不同
形参的数量和类型都不同
如果返回类型不同而函数名相同 形参也相同则是不合法的。会报语法错误
编译器识别时对重载函数进行了名字改变 所看到的函数名字其实是不同的
名称粉碎/名字改编机制
函数前extern“c”就代表了不进行函数改编 所以c不支持函数重载 ?在c++中能否用extern关键字?效果等同于c
默认参数
形参默认赋值
c++函数声明的时候,给形参赋一些默认值
规则
函数没有声明的时候 在函数定义中指定形参的默认值
声明与定义的区别
声明:向程序表明变量的类型和名字 在哪里可以找到
定义:为变量分配存储空间,可为变量指定初始值 变量有且仅有一个初始值
函数定义和声明都有的时候,声明时指定函数名 函数参数及函数体,定义后,不能在指定默认值(已有初始值)
当使用了默认参数的同时还使用了重载易造成二义性
默认值定义必须遵守从右到左的顺序,如果某个形参没有默认值,
那么它左边的参数就不能有默认值(间隔问题) 只考虑顺序不考虑多少
编写时对部分函数参数定义的时候就进行赋值减少传参量
如果一个函数有一些参数的值往往都是一样的时候就可以给它设置一个默认值在调用的时候就无需主动
传递实参
引用
和指针类似 用法不一样
指针:int*p=&nNum;
引用语法 int&r=nNum; & 引用符号 标志 r是引用类型变量
定义时在关键字(决定引用类型)后加‘&’ ?类型不一致问题
返回值类型问题 (语法报错)
static 不可以修饰函数形参
引用类型的变量必须要初始化 初始化的时候必须要引用一个变量 不可引用常量
引用类型的变量不占用内存空间,它的内存就是所引用的变量的内存空间 通过引用可以直接访问到被引用
的变量的值,修改了引用类型的变量或者修改被引用类型的变量,双方都会受到影响(因为它们使用的同一块
内存空间。)
必须被初始化; ?NULL 置空问题//不会有野指针 相当于直接操作变量
不能再引用其他变量;
局部变量引用出错 函数变量生存期问题(参数内存会被销毁) 不会报错语法可行(玄学)
eg:对比变量交换 ?void未有内存空间的时候//不可以引用
?加const 表示此时为常量引用 不能修改此内存 优先给指针加const
c:
void swap(int **pLeft,int ** pRight)
{
int* temp=*pLeft;
*pLeft=*pRight;
*pRight=*pLeft;
}
c++:
void swap(int *&pLeft,int*& pRight)
{
int*temp =pLeft;
pLeft=pRight;
pRight=pLeft;
}
应用常识
c 值传递 拷贝
地址传递 拷贝 只拷贝4个字节 不会占用内存空间 地址访问
c++ 引用 不占内存空间(语法层面) 高效 直接访问
使用引用作为参数的时候
底层会改成指针形式 本质一样 汇编层面理解
const引用
const型引用 可以引用普通数据
输入输出
头文件 iostream
using namespace std;
流:<< >>
c:printf scanf
非类型安全 没有类型检查 通过格式控制字符严格控制 错误的控制符不会报错
不可扩充性 只能输出基本类型 无法输出拓展类型(结构体或对象)
c++:cout cin 非函数 本质为变量 全局对象
cout输出流
输出使用插入操作符<< 向 cout输出流中插入字符
使用‘<<’将要输出的数据传递给cout输出到控制台
eg:cout<< "this is a program"
cin 输入流
输入使用抽取操作符>> 从cin输入流中抽取文字 不需要取地址 自动识别数据类型
从控制台获取一个整数,然后存储到nNum
cin>>nNum;
不需要格式化控制符 按照数据智能接受相应的数据
eg:int i;float f;long i;
cin>>i>>f>>l;
c++中的头文件都没有.h结尾文件 专门提供了c++版本的头文件
eg:
规律:以c打头 没有.h后缀
endl 表示换行 并刷新输出缓冲区
eg:cout<<"nNum="<<nNum<<endl;
输出流控制符
dec 按10进制输出
hex 按16进制输出
oct 按8进制输出
setfill(c) 设置填充字符为c 默认填充为空格
setprecision(n) 设置显示小数精度为n位(包括小数点之前的数值 先设置小数方式表示)
set(w) 设置域宽为n个字符
setiosflags(ios::fixed) 小数方式表示
setiosflags(ios::scientific) 指数方式表示 (科学计数法)
setiosflags(ios::left) 左对齐
setiosflags(iso::right) 右对齐
命名空间
作用域:
c: 文件作用域 eg:全局变量
函数作用域
代码复合语句{} ?结构体 联合体//!
c++: 带名称的作用域 (命名空间)
类域
命名空间 名字空间 名称空间
用来限定名称的解析和使用范围以解决命名冲突
命名空间只能在全局范围内定义(一个命名空间名有且只有一个定义 定义即赋予初始化空间内存)
‘命名空间名’是c++合法的标识符,也可以使用作用域分解运算符'::'来构成命名空间的完全限定名
,可以没有命名空间名(无名的命名空间),其成员的名称完全不需要限定就可以使用,
不允许在定义命名空间的时候使用任何访问修饰符,默认命名空间具有public访问属性
命名空间的成员可以是另一个命名空间(嵌套)或类型(类,结构 结构 枚举)的定义
一个命名空间可以在多个头文件中使用一个标识符来定义
一个命名空间可以使用另一个名字来做它的别名
不能像类一样去创建一个命名空间
可以在编译单元中包含一个未命名的命名空间,但只能包含一个未命名的命名空间(?可有其他多个?)
命名空间结尾,右花括号的后面可以跟一个分号';';
格式
namespace 命名空间名
{
命名空间成员(其他命名空间或类的定义) ?嵌套自身// 不可以
}
使用命名空间
void std::fun()
{
cout<<"15PB::fun"<<endl;
}
int main()
{
std::fun();方式1 直接在符号名前加作用域
using std::fun; 方式2 使用Using关键字相当于使用单个符号的时候,不需要加作用域
fun(); 但使用其他的符号还需要加作用域(如果空间外有重名符号会造成二义性,应避免使用)
using namespace std;方式3 使用Using指令把所有名字引入到命名空间中
}
命名空间别名(减少敲码量)
语法:
namespace 别名=命名空间名
|