文章目录
全局类型增强
在c的代码中,允许在同一个作用域下声明多个同名变量的
c
#include <stdio.h>
int a = 10; // 全局变量
int a; // 只有声明,没有赋值
// 在c的代码中,允许在同一个作用域下声明多个同名变量的
int main()
{
printf("a=%d\n", a);
}
注意,a必须是全局变量,如果写到main()函数里面,也会报错
但是上述代码这种情况对C++来说就会报错,会认为是重复定义
参数类型增强
c++中所有函数的参数都要有类型,c中函数的参数,可以没有参数类型
在c中,允许函数的参数只有参数名,没有参数类型的
当函数的参数没有参数类型时,说明这个函数允许任何类型的参数传过来
c
int test(i) {
printf("%d\n", i);
return 0;
}
int main(){
test(5); //打印5
test('A'); //打印65,根据ASCII
}
在c中,在函数定义时,没有写任何参数,这说明这个函数不是没有参数而是在调用时可以传入任意类型,任意多个参数
虽然调用时可以传递任意参数,但是这个参数因为在函数中,没有使用,所以没有任何意义在c中,如果函数不想接收任何参数,那就要加
void
c
int test()
{
printf("test\n");
}
int main()
{
test(); //能正常打印
test("string", 50, 'A');//也能正常打印
return 0;
}
结构体类型增强
在c++中对结构体类型做了增强:
1 c++中,允许结构体中既有成员变量,也有成员函数
2 在使用时声明结构体时,可以不加struct关键字
c++代码:
cpp
struct Student
{
string name = "lisi";
int age = 20;
void printStu()
{
cout << "name:" << name << " age:" << age << endl;
}
};
int main()
{
Student stu;// 在c++中,使用结构体时,可以不加关键字struct
stu.name = "zhangsan";
stu.age = 30;
stu.printStu();
}
在C++中这个结构体就是面向对象中的类,定义一个struct结构体,就是定义一个类
bool类型的增加
在c++中,有新增一个类型bool(bool类型一共就只有两个值),专门来表示true false
一共有三个关键字 bool true false
C++:
cpp
bool flag = true; // true 是 C++ 关键字
bool isReady = false; // false 是 C++ 关键字
// bool 占用 1 个字节(通常)
cout << sizeof(bool) << endl; // 通常是 1
// bool 值实际上就是 0 或 1
bool b1 = true;
cout << b1 << endl; // 输出 1
bool b2 = false;
cout << b2 << endl; // 输出 0
C语言:
c
// C 语言中没有 bool 类型
// 通常用 int 或 char 模拟
#define TRUE 1
#define FALSE 0
int flag_c = TRUE; // 使用宏定义
三目运算符增强
在C语言 中,三目运算符的结果不能 当左值使用,但是在C++中,三目运算符的结果能当左值使用
cpp
void test6()
{
int a = 10;
int b = 20;
cout << "a=" << a << " b=" << b << endl;
// 在c++中,以下代码不报错,因为c++中,三目运算符返回的是左值a b
(a > b ? a : b) = 100;
cout << "a=" << a << " b=" << b << endl; //此时a还是等于10,b就等于100
}
const增强
关于const的面试题
cpp
void test()
{
const int a = 10;// a不能直接修改,但是可以通过指针间接修改
int* p1 = (int*)&a; // 这个地方必须强转一下,否则会报错
*p1 = 100;
printf("*p1=%d\n", *p1);
printf("a=%d\n", a);
}
其实这个代码的结果完全取决于编译器是否优化,比如对C++来说, *p1 = 100 ,a = 20 ; 但是如果把代码放在C语言文件中,得到的结果就都是100,但是对于
并且优化方案也有两种情况
优化方案1:
根据代码继续讲解
cpp
void test() {
const int a = 10; 虽然是const,但刚开始a在栈上分配了内存
int* p = (int*)&a; 获取地址
*p = 100; 修改了a的那块内存
printf("*p=%d\n", *p); 从内存读:100
printf("a=%d\n", a); 编译器优化,直接使用10,不读内存
}
优化方案2:
cpp
。
void test() {
const int a = 10; 编译器会把它放到符号常量表中,不会立即分配内存
int* p = (int*)&a; 获取地址,此时才会给a分配内存空间
*p = 100; 修改了a的那块内存
printf("*p=%d\n", *p); 从内存读:100
printf("a=%d\n", a); 编译器优化,直接使用10,不读内存
}
两种优化方案的不同就在于是否一开始对a进行栈内存中的分配,但其实都是打印a的时候都没有去内存,
要想让编译器取消这种优化,可以对变量a加volatile关键字取消优化,此时的变量a的值也会为100,因为打印的确实是内存中的a的值
函数重载
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型
不同的问题。
1、参数类型不同
cpp
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
2、参数个数不同
cpp
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
3、参数类型顺序不同
cpp
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
为什么可以发生函数重载?
本质是C++中进行了函数名修饰
比如下面这段代码
cpp
int Add(int a, int b)
{
return a+b;
}
void func(int a ,double b, int* p)
{
//空
}
现在我们通过objdump -S 看汇编代码
首先看C语言文件的情况

可以看到C语言代码汇编下这个函数名并没有任何修饰与变化
接下来再看看C++的:

可以看到C++代码在汇编下这个函数名被进行了修饰,并且修饰信息就是与参数列表的类型
注意:函数重载与返回值类型毫无关系! ! !
缺省参数(默认参数)
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。
在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
cpp
void Func(int a = 0)
{
cout<<a<<endl;
}
int main()
{
Func(); /没有传参时,使用参数的默认值
Func(10); /传参时,使用指定的实参
return 0;
}
缺省参数分类:
1.全缺省:
cpp
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
2.半缺省
cpp
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
注意:
1.半缺省参数必须从右往左 依次来给出,不能间隔着给,
2.如果你有了多个缺省参数,但你调用函数的时候只写了一个参数,那么这个参数是赋值给左边的,从左往右 赋值(注意区分第1点的从右往左).
3.并且对于使用了缺省参数函数,并且函数的声明和定义分开时 ,是需要将默认参数写在声明中 的,在定义时就不要再写默认值了.
最后再提示一点:
cpp
注意事项:当默认参数遇到函数重载的时候,要注意避免产生二义性
void func(int a)
{
cout << "a=" << a << endl;
}
void func(int a, int b = 10)
{
cout << "a=" << a << " b=" << b << endl;
}
int main() {
func(5); /编译错误:ambiguous(二义性)编译器不知道调用哪个:
/1. func(int a) → 匹配
/2. func(int a, int b = 10) → 也匹配(b使用默认值)
}
函数的占位参数
c++在声明函数时,可以设置占位参数。占位参数只有参数类型声明,而没有参数名声明。一般情况下,在函数体内部无法使用占位参数。
占位参数 :只有参数类型,没有参数名,只起一个占位的作用,没有实际意义.
为什么需要占位参数? 当有某几个函数,他们的参数列表一样,但是内部的逻辑不一样的时候为了区分,就需要使用占位参数,如果函数中存在占位参数,那么在调用时,传入任意值都是可以的,只要类型保持一致就可以
cpp
int calcFunc(int a,int b)
{
return a+b;
}
int calcFunc(int a, int b,int)
{
return a-b;
}
int main()
{
int n = calcFunc(60,10); /加法
int m = calcFunc(60, 10, 1);/有一个占位符,减法
cout << n << endl <<m << endl;
return 0;
}
这两个函数的函数名相同,但是一个是加法函数一个是减法函数,此时因为函数名相同,所以用占位符来区分,调用该函数的时候,并且这个占位符的数字可以是任意数字,并不局限于上述代码中的1.