C与C++的区别有哪些?
C是面向过程的,C++是万物皆是对象,那么实质上这两者之间有什么区别呢?这边文章帮助你记忆一下。
主要区别:
C与C++的区别:
- 1、输入与输出
- 2、引用
- 3、inline函数
- 4、函数默认值
- 5、函数重载
- 6、模板函数
- 7、new/delete
- 8、namespace
1、输入与输出
一个例子来说明:
//首先对于标准库的引用:
//c中
#include<stdio.h>
//C++
#include<iostream>
using namespoace std;//还要加上命名空间
int main()
{
int a;
char c;
scanf("%d %c",&a,&c);
printf("%d %c",a,c);
cin>>a>>c;
cout<<a<<c<<endl;
}
<< (中j间无空格)称作提取符
cin代表标准输入设备,这实际上是一个对象
cin>>a>>c;//代表从键盘上提取一个a一个c,连续提取多个变量一定要用>>隔开,而不能用,隔开,也就是在这里会先将提取到的数据放到缓冲区,然后依次来提取给变量。
<<插入符
cout彼岸准输出设备,也是一个对象
cout<<a<<c<<endl;.//代表把a插入到标准输出设备,再将c插入到标准输出设备(这里的endl实际上是一个方法,后面会说,他会执行一个\n操作来换行)。
2、引用
在C++中,引用就是别名的意思,相当于给一个东西多起了一个外号,但实际上,他们指的是同一个。
类型& 引用名称 = 变量名称;
这里区别于C,不是取地址的意思
int a=10,b=20;
int c=0;
c=a && b;//这里&&是逻辑与
c=a & b;//这里&是按位与
int *p=&a;//这里是取地址
int &x=a;//这里是引用(别名)
int func(int &a)//这里说明传递进来的是一个int型的引用
{
...
}
int& func()//这里说明函数会返回一个引用
{
...
}
引用的使用:
- 引用必须要初始化,不能有空引用
- 引用不分级别,没有引用的引用
常引用:
- const int & a=n;
- 能力可以收缩,不可以扩展
- 引用做函数参数
3、inline(内联函数)
内联函数的处理方式是在函数的调用点直接展开代码。在计算机系统下,假如频繁的调用就会造成较大的时间开销。所以,内联函数的引入减少了函数调用过程中开栈和清栈的开销。
我们知道,时间开销会包括现场保护和现场恢复,涉及到中断等…
- 内联函数和普通函数的区别:
内联函数在函数的调用点直接展开代码,没有开辟栈和清栈的开销。普通函数有开栈和清栈的开销。
内联函数要求代码简单,不能包含复杂的结构控制语句。
若内联函数体过于复杂,编译器将自动把内联函数当成普通函数来执行。 - 内联函数和static修饰的函数的区别:
static修饰的函数处理机制只是将函数的符号变成局部符号,函数的处理机制和普通函数相同,都有开栈和清栈的开销。内联函数没有开栈和清栈的开销。
inline函数是因为代码直接在调用点展开导致函数只在本文件可见。而static修饰的函数是因为函数法符号从全局符号变成局部符号导致函数本文件可见。 - 内联函数和宏的区别:
inline函数的处理时机是在编译阶段处理的,有安全检查和类型检查。而宏的处理是在预编译阶段处理的。没有任何的检查机制,只是简单的文本替换。
inline函数是一种更安全的宏。
但是内联函数以空间为代价,有可能会引起代码膨。
debug下,不存在内联,只存在于release版本。
inline函数只是给编译器的一个建议,到底用不用是由编译器决定的。
内联资格:完成单一功能,代码少
4、函数参数的默认值
void fun(int a,int b,int c=0,int d=0,int e=0)//函数给默认值一定是从右向左给的,不能跳跃
{
printf("%d %d %d %d %d\n",a,b,c,d,e);
}
int main()
{
fun(12,23,41);//一定是41给c,23给b,12给a
//fun(12, ,23);//error
fun(12,7,(551,14,9,63),71);//这里a=12,b=7,c=551,d=71,e=0,逗号表达式取第一个值
}
5、函数的重载
函数的原型包括函数返回类型、函数名、形参列表(参数类型和个数,其中形参名可以省略),且不需要函数体。
extern是外部关键字,extern“C”表示按照C方式处理,一般是给函数名前面加_下划线,因此可能会出现命名冲突的问题,而无法重载。extern“C++”按照C++方式处理。
为什么C++能进行重载? 因为有粉碎技术(名字重命名规则)。
首先,C的函数调用约定:
而在C++中:
int Max(int a,int b)
{
return a>b?a:b;
}
double Max(double a,double b)
{
return a>b?a:b;
}
char Max(char a,char b)
{
return a>b?a:b;
}
int main()
{
Max(10,12);
Max(1.2,2.3);
Max('a','b');
return 0;
}
生成的函数名是这样的:
注意调用的二义性!(返回值有时候不能区分;参数个数不一定了(带默认值就不一定行了))。
6、函数模板
定义:
编译时确定类型(做typedef int Type;)
模板是产生代码的代码,模板不是宏替换,是重命名
泛型编程:以函数的产生为代价
7、命名空间
命名空间的引入是为了解决全局变量名污染问题。
namespace xxx
{
void fun(int a)
{
a+=10;
}
int main()
{
int a=10;
xxx::fun(a);//::是作用域解析符
return 0;
}