一.什么是C++
C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计(本质面向对象,可以按照面向过程的方法使用c++),还可以进行以封装、继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应的问题规模而论,大小由之。C++不仅拥有计算机高效运行的实用性特征,同时还致力于提高大规模程序的编程质量与程序设计语言的问题描述能力。
二.五大区分析与作用域分析
- 堆:就是那些由malloc或new(自由存储区)分配的内存块,它们的释放编译器不管,由我们的应用程序控制,一般一个malloc或new就要对应一个free或delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。内存泄漏
- 栈:就是那些由编译器在需要的时候分配,不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。主函数的栈区相当于全局变量区
- 全局/静态存储区:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(放在data端), 未初始化(放在bss段)的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
- 文本常量区 :常量字符串、其它常量就是放在这里的。 程序结束后由系统释放。(对于局部的const 非static常量,放在栈区而非常量区。而全局的const 放在常量区里。)
单片机:flash程序存储器
PC:ROM
- 代码段:通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
三.C/C++关键字
四.输入输出
cin:代表标准输入设备,使用提取运算符”>>”表示从设备键盘中获取数据,输送到cin(输入流),然后送到内存;
cout:代表标准的输出设备, 使用提取运算符”<<”把输出内容存放在输出缓冲区,再有输出缓冲区送到屏幕;
endl:”结束此行”,作用两个:换行、输出流进行刷新;
不管cin、cout 都能自动判定相关数据类型;比如一个char变量,cin进行输入char;
#include <iostream> //i:input o:output stream 流
using namespace std;
int main()
{
/****************c*****************/
int a;
scanf("%d",&a);
printf("%d\n",a);
/****************c++**************/
char buff[30];
cin>>buff; //
cout<<buff<<endl; //类似于\n 输出缓冲区送到屏幕
while(1);
return 0;
}
五.C/C++数据类型区别
C语言:char int short long float double 构造数据类型 char buff[128] 结构体 共用体 枚举C++语言:char int short long float double char buff[128]strcpy 结构体 共用体 枚举
介绍C++中比较常用的数据类型(类) string,可以用 char* 类型的变量、常量,以及 char 类型的变量、常量对 string 对象进行赋值。
区别 |
C语言 |
C++ |
字符串类型 |
Char 数组名[]=”字符串” |
沿用c风格: Char 数组名[]=”字符串” C++风格: string 变量名 =“字符串” 注意相关头文件:#include <string> |
六.引用
引用是为已存在的变量取了一个别名,引用和引用的变量共用同一块内存空间。
引用:int &b = a;
- 引用创建的时候必须初始化,不能指定为NULL。
- 引用必须与一个合法的单元连用
- 引用并不是创建一个数据类型,它不是一个独有的类型
- 引用不能返回局部变量
- 引用在只在定义的时候加&
- 引用只是一个别名,不占内存(编译器处理)
- 引用在形式上是指针常量,引用以后指向不能发生改变。
- 一个变量可以有多个引用,不同的引用不同的空间。
C语言中:指针:指针常量 常量指针 常量指针常量
1.引用作为函数返回值作用
int &Function(void)
1.引用作为函数的返回值时,必须在定义函数时在函数名前将&。
2.用引用作函数的返回值的最大的好处是在内存中不产生返回值的副本。
3.函数返回值可以是一个对象引用,在这种情况下函数中的return语句必须返回一个变量或可以做为左值的表达式。
返回值
#include <iostream>
using namespace std;
//引用作为返回值 引用类型
int & Function(int & a) // int & a=x1
{
return a;
}
int main()
{
int x1=5;
cout<< x1<<endl;
int &P = Function(x1);
cout<< x1<<endl;
return 0;
}
2.引用做左值
#include <iostream>
using namespace std;
//引用作为返回值 引用类型
int & Function(int & a) // int & a=x1
{
return a; //int a = 10; int a = 10;代码段立即数
}
int main()
{
int x1=5;
cout<< x1<<endl;
//作为左值:
int &P = Function(x1);
Function(x1)=9999;
cout<< x1<<endl;
return 0;
}
返回局部变量--err*注意:不要返回局部变量的引用,原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为”无所指”的引用,程序进入未知状态。
3.引用做常量
传常量参数的时候必须加const
int Function(const int & num)
例:传参常量10,默认选择const int &num
#include <iostream>
using namespace std;
//引用作为返回值 引用类型
void Function(const int & a) // int & a=x1 const int *const p常量指针常量
{
cout<< a<<endl;
}
int main()
{
int x1=5;
cout<< x1<<endl;
Function(10);
cout<< x1<<endl;
return 0;
}
七.函数
1.C++具有默认参数
C++规定,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。实参和形参的传值是从左到右依次匹配的,默认参数的连续性是保证正确传参的前提。
#include <iostream>
using namespace std;
//C++规定,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。实参和形参的传值是从左到右依次匹配的,默认参数的连续性是保证正确传参的前提。
void function(int a=10, int b=99)
{
cout<<"a:"<<a<<" "<<"b:"<<b<<endl;
}
int main()
{
function(10);
return 0;
}
2.二义性
声明和定义函数的形参都有初始值,就会造成二义性。
解决办法:一般在定义时候不给默认值,在声明的时候给默认值。(声明时没有定义缺省参数值,那么在定义成员函数时可以定义缺省参数值。但这种情况通常用户是看不见的,因此应避免。对于非类中的函数,在函数声明中定义默认参数的另外一个好处时,可以利用声明来随意更改默认参数的值。)
3.函数占位参数
占位:只有参数类型声明
①C++在声明函数时,可以设置占位参数。占位参数只有参数类型声明,而没有参数名声明。一般情况下,在函数体内部无法使用占位参数。
②C++中函数的参数列表中可以实现占位参数,调用函数时,必须把该位置进行补全。
#include <iostream>
using namespace std;
void function(int a,int b,int);
int main()
{
function(10,10,10);
return 0;
}
void function(int a, int b,int)
{
cout<<"a:"<<a<<" "<<"b:"<<b<<endl;
}
八.函数重载
所谓函数重载是指同一个函数名可以对应多个函数的实现,这些具有相同名称的函数称为重载函数集; 函数重载的好处就是可以给予不同的初始条件(参数), 来处理相同的事情
函数重载四要素:
-
作用域相同
-
函数名一致
-
返回类型相同
-
参数的类型、个数不同
#include <iostream> //i:input o:output stream 流
using namespace std;
//引用做参数
void fun(int & a,int &b);
void fun(const int & a,const int &b);
//int int
int Add(int& a, int& b)
{
cout<<"int Add(int& a, int& b)"<<endl;
return 1;
}
int Add(const int & a,const int & b )
{
cout<<"int Add(const int a,const int b )"<<endl;
return 1;
}
int main()
{
int x1=10,x2=20;
Add(x1,x2);
//Add(10,20);
return 0;
}
九.extern “C”
按照C语言风格编译。
extern “C”是链接指示符,主要作用是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后会指示编译器将这部分代码按C语言进行编译,而不是C++,由于C++支持函数重载,因此编译器在编译函数的过程中会将函数的参数类型也加到编译后的代码中,不仅仅是函数名;而C语言并不支持函数重载,因此在编译C语言代码的函数时不会带上函数的参数类型,一般只包含函数名;
①C++代码调用C语言代码;
②在C++的头文件中使用;
③在多个人协同开发时,可能有的人比较擅长C语言,而有的人擅长C++,这样的情况下也会有用到
10.一些注意点
1.
C++引用的相当于C语言的指针常量。即地址不变,地址内容可以改变。
C语言中的指针是地址是可以变化的。
2.
c++无法区分这样的重载:c++重载要求参数的类型或者数量不同,其中的类型必须是独立的类型,引用依赖于被引用的对象而存在,它不是一个独立的类型,引用和值对于函数的调用形式来说没有任何区别,编译器无法区分值和引用的重载导致二义性错误,所以不要做这样的重载!
3.
void swap(int a,int b):只读
void swap(int *a,int *b);传址 可写
void swap(int &a,int &b);传引用 可写
传值:目标对象重新开辟一个完全相同的内存栈空间,然后把对象的值复制到栈中
传地址:传递的是指针的值,系统在栈中开辟空间存放地址,函数内部的指针是原始指针值的副本,它们都指向同一个对象的内存地址,但它们是不同的指针变量。
传引用:真正的以地址的方式传递参数,传递以后,形参和实参都是同一个对象,只是他们名字不同。
请看下面示例:
#include "stdio.h"
#include <stdlib.h>
void fun1(int *p)
{
p = (int *)malloc(4);
}
void fun2(int *&p)
{
p = (int *)malloc(4);
}
int main()
{
int *p;
printf("p:0x%p\n",p);
fun1(p);
printf("p:0x%p\n",p);
fun2(p);
printf("p:0x%p\n",p);
}
输出结果:
可以看到,当传指针的时候,由malloc分配的地址是不能传入实参的。这是因为传递地址以后,系统在栈中开辟空间存放地址,实参和形参都指向同一个对象。实际malloc的地址被分匹配到副本里。
可以在涉及的函数中修改指针的内容,指针的内容一旦发生改变,实参和形参都会同步内容。
4.
左值:表达式运行完毕后仍然存在的持久对象。
右值:表达式运行完毕后不存在的临时对象。
左值相当于地址值,右值相当于数据值。左值表示存储在计算机内存的对象,而不是常量或计算的结果。或者说左值是代表一个内存地址值,并且通过这个内存地址,就可以对内存进行读并且写(主要是能写)操作
比如:++i和i++ ++i:可以做位左值,因为它先计算,后赋值,返回的是i本身,可以通过i地址进行读写数据。