1、c++与c的关系
(1)、c++是c的增强版,是在c的基础上增加了新的特性,并且加入了面向对象的编程思想,c++是完全兼容c的
(2)、c语言是面向过程的,c++是面向过程+面向对象的
(3)、c++相当于c编程效率会更高,更适合大型的应用程序
(4)、c++的特点:
①、可以用于游戏开发、服务器开发、嵌入式等等
②、面向对象的三大特性:封装、继承、多态
③、自由的、开放的编程语言
④、c++一切皆对象
2、命名空间
回忆c语言:同一作用域的变量或者函数名不可以重名,但是只要作用域不同就可以重名
所以:全局变量是不能重名的
命名空间的作用:防止命名冲突的
定义:
namespace 命名空间名
{
变量的定义;
函数的定义;
类型名的定义;
};
使用方法:
1)命名空间名::变量名;
2)using namespace 命名空间名;
直接使用变量
代码实现:
//这里我先采用了C语言的编写
#include <iostream>
#include <stdio.h>
using namespace std;
int i=0;//全局变量
void func()
{
int i=1;
printf("global i=%d i=%d\r\n",::i,i);
}
namespace demo{
int i=2;
void func()
{
int i=3;
printf("global i=%d demo::i=%d i=%d\r\n",::i,demo::i,i);
}
}
int main()
{
#if 0
using demo::func;//声明使用demo中的func
using demo::i;//声明使用demo中的i
func();
printf("i=%d\r\n",i);
#endif
demo::func();
printf("demo::i=%d\r\n",demo::i);
return 0;
}
3、输入输出流
cout和cin:标准的输出和输出流
cout:显示屏
cin:键盘
类似于c语言中的scanf和printf
cin和cout是对象
头文件:
#include <iostream>
using namespace std;
代码实现:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
cout<<"hello 22071\r\n";
int i=10,j=20;
char k='a';
cout<<"i="<<i<<" j="<<j<<" k="<<k<<endl;
cin>>i>>j>>k;
cout<<"i="<<i<<" j="<<j<<" k="<<k<<endl;
return 0;
}
4、引用
引用:给变量起一个别名,本质就是一块空间有多个名字,这块空间通过这多个名字都可以直接进行访问,所以:访问引用就是在访问变量
定义:int a = 10;
int &b = a; //b就是a的引用 b就是a的别名
一块空间有两个名字,一个是a,一个是b
引用的应用:
1)函数的形参,可以避免临时空间的产生
2)函数的返回值,返回的是实参本身,可以避免临时空间的产生
注意:
1)引用必须初始化
2)&在赋值运算符左边就是引用,在赋值运算符右边就是取地址
3)引用也可以有引用
常引用:常量也可以有引用
const int &a = 10; //a是10的别名 和#define作用一样,比#define更好用
const int &a = b; //a是b的别名,但是a不能被修改
代码实现:
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
#if 0
int a=10;
int &b=a;
b=20;
printf("a=%d b=%d\r\n",a,b);
printf("&a=%p &b=%p\r\n",&a,&b);
#endif
#if 0
int a=100;
int &b=a;
int &c=a;
int &d=a;
printf("a=%d b=%d c=%d d=%d\r\n",a,b,c,d);
#endif
#if 0
int a=100; //多级引用
int &b=a;
int &c=b;
int &d=c;
printf("a=%d b=%d c=%d \r\n",a,b,c);
#endif
int a=100;
const int &b=a;//b为常引用
//b=200;
printf("a=%d b=%d\r\n",a,b);
return 0;
}
ps:指针和引用的区别?
1)本质区别:指针会产生新的空间的,是通过知道变量的地址来进行间接访问,引用是不会产生新的空间,访问引用就是在访问变量,是直接访问
2)在使用上的区别:
①指针可以不用初始化,但是引用必须被初始化
②有void *类型的指针,但是没有void类型的引用
③指针+1,向地址增大的方向移动了1个数据,引用+1就是变量的值加了1
④有数组指针,函数指针,但是没有数组引用和函数引用
⑤指针只能指向字符串常量,但是常引用可以是任何常量的引用
⑥有二级指针,但是没有二级引用
⑦指针的指向可以发生改变,而引用不能被改变
⑧指针占内存空间,而引用不占内存空间
5、函数重载
函数功能类似,函数名相同,参数不同(类型和个数),与返回值无关,叫做函数重载
那如何区分要调用的是哪一个函数呢?通过参数来区别
思考:函数的本质是存在于内存中的一段二进制代码,而函数名是这块内存空间的首地址,函数名既然是首地址,怎么可以重名呢?
实际上c++是给函数进行重命名了,根据函数名+函数参数进了重命名
比如:fun(void)---》fun_v(void)
fun(int)--->fun_i(int)
fun(int, int)-->fun_i_i(int, int)
代码实现:
#include <iostream>
#include <stdio.h>
using namespace std;
int add(int a)
{
printf("one int----------\r\n");
return a+a;
}
int add(int a,int b)
{
printf("two int----------\r\n");
return a+b;
}
double add(double a,double b)
{
printf("two double-----------\r\n");
return a+b;
}
double add(double a, double b,double c)
{
printf("three double----------\r\n");
return a+b+c;
}
int main()
{
printf("1:%d\r\n",add(10));
printf("2:%d\r\n",add(10,20));
printf("3:%f\r\n",add(10.0,20.0));
printf("4:%f\r\n",add(10.0,20.0,30.0));
return 0;
}
6、默认参数
默认参数:在函数声明时,函数的参数可以有默认值
注意:
1)如果函数声明和函数定义是分开的,那么只能在函数声明时有默认参数,函数定义就不需要了,否则就会出现重复定义
2)默认参数只能是从右往左存在,而且必须是连续存在
代码实现:
#include <iostream>
#include <stdio.h>
using namespace std;
int func(int a,int b=10)
{
return a+b;
}
int func1(int a=10,int b=10,int c=10)
{
return a+b+c;
}
int func2(int a,int b=10);
int func3(int &a,int &b)//默认参数不能是引用变量名
{
return a+b;
}
int func4(int a)
{
return a+a;
}
int func4(int a,int b=10)
{
return a+b;
}
int main()
{
printf("1:%d\r\n",func(10,20));
printf("2:%d\r\n",func(10));
printf("3:%d\r\n",func1(100));
printf("4:%d\r\n",func2(100,200));
int x=100,y=200;
printf("5:%d\r\n",func3(x,y));//300
printf("6:%d\r\n",func4(100,300));
//printf("7:%d\r\n",func4(100));//默认参数和函数重载一起使用,产生了二义性
return 0;
}
int func2(int a,int b)
{
return a+b;
}
7、c++调用c库的函数
c++是完全兼容c语言的,c++中可以出现c语言,而且c++可以调用c库的函数
c++调用自己定义的c库(使用gcc已经编译好的二进制,因为c库的函数不仅是要给c++程序使用,还要给c程序使用)的函数如何实现?
解决这个问题的方法只能是:使用同样的编译器,但是又有新的问题了,不能因为一个调用了一个c库的函数,就把整个c++程序用gcc编译吧,这是不现实的,只能选择编译了,只把fun函数用gcc编译,其他部分还是使用g++编译
如何告诉g++使用gcc编译使我们现在要解决的问题?
所以,如何区分此时是g++在编译还是gcc在编译是我们要解决的根本问题
编译器在设计的时候,已经将它两的区别设计好了
第一种方法:
g++里有__cplusplus这个宏,而gcc没有
第二个方法:
g++里面sizeof(‘a’)=1,gcc里面sizeof(‘a’)=4
8、new和delete运算符
new和delete的作用跟malloc和free是一样的
new:在堆区申请空间
delete:在堆区释放空间
ps:
int *p = (int *)malloc(4); free(p);
int *p = new int; delete p;
int *p = (int *)malloc(sizeof(int) * 10); free(p);
int *p = new int[10]; delete []p;
总结:malloc与free和new与delete的区别:
1)malloc和free是c库函数,new和delete是运算符
2)malloc和free需要强制类型转换,而new和delete不需要
3)malloc需要计算申请空间的大小,new不需要,只需要指定元素个数就可以
4)代码实现:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
//申请一个存放整形元素的空间
int *p=new int;
*p=100;
printf("*p=%d\r\n",*p);
delete p;
//申请一个存放整形元素的空间,并初始化成200
int *q=new int(200);
printf("*q=%d\r\n",*q);
delete q;
//申请可以存放五个整形元素的数组,并赋值
int *pp=(int *)malloc(20);
if(pp)
{
for(int i=0;i<5;i++)
{
pp[i]=i+10;
printf("%d ",pp[i]);
}
printf("\r\n");
}
free(pp);
//new delete 数组
int *qq=new int[5];
if(qq)
{
for(int j=0;j<5;j++)
{
qq[j]=j+20;
printf("%d ",qq[j]);
}
printf("\r\n");
}
delete[] qq;
return 0;
}