C++:对C语言的增强
一、全局变量增强
C语言:1、仅有一个全局作用域,标识符之间可能发生冲突;
2、同一变量可重复定义。
C++ :1、namespace命名空间将全局作用域(默认命名空间)分为不同部分,可有效避免标识符冲突,且命名空间可以相互嵌套;
2、变量不可重复定义
int main()
{
int var;
int var = 1; // 在c语言中可以存在重复定义,但在c++中不行
}
C++标准为了和C区分开,也为了正确使用命名空间,规定标准库头文件不适用后缀.h。
二、函数检测增强
1、形参变量类型检测增强:C++中所有形参须给定类型。
2、函数声明返回值类型检测增强:C++中须明确声明返回值类型,且实际返回值类型应与声明类型相同。
3、函数调用参数传入个数检测增强:C++中函数参数传入个数应与实际声明个数相同。
三、类型转换检测增强
语句int* p = (int*) malloc(sizeof(int))中,malloc开辟动态空间默认类型为void*
C语言:可不用强制类型转换直接赋值给类型为int*的变量p;
C++ :须先进行强制类型转换才可赋值。即赋值语句中,左值与右值类型须相同。
四、struct增强
1、C语言中结构体里不能放函数,而C++中可以;2、C语言中结构体声明须加关键字struct,C++中结构体声明可以省略struct关键字。
#include <iostream>
#include <string>
using namespace std;
struct Student
{
char name[64];
int age;
int add(int x, int y) // C++中struct中可以包含函数
{
age++;
return x + y;
}
};
int test01()
{
Student s = {"lisi", 19};
cout<<"Name: "<<s.name<<", Age: "<<s.age<<endl;
int a = s.add(3, 5);
cout<<"Name: "<<s.name<<", Age: "<<s.age<<endl;
cout<<"a = "<<a<<endl;
return 0;
}
五、三目运算符增强
C语言:三目运算符返回的是变量的值,即三目运算符不能做左值。
C++ :三目运算符返回的是变量,即可做左值。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 10;
int b = 20;
(a<b?a:b) = 100;
cout<<"a = "<<a<<endl; // a = 100;
cout<<"b = "<<b<<endl; // b = 20;
}
六、const增强
C语言:const 修饰的变量成为常变量,不能初始化数组。
1、全局const:
const int var = 100;
int main()
{
// var = 200; // 直接修改一定不成功;
int* p = (int*)&var;
*p = 200; // 可以正常编译,运行错误。全局常量存放在常量区,受常量区保护。
}
2、局部const
int main()
{
const int var = 100;
// var = 200; // 直接修改一定不成功;
int* p = (int*)&var;
*p = 200;
// var = 200.修改成功。局部const修饰的变量为常变量,存放在栈区,可以间接修改。
printf("var = %d\n", var);
// int arr[var]; C语言中,无论是全局常变量,还是局部常变量均不能初始化数组。
}
3、const修饰的全局变量默认是外部链接属性,即可以在同一项目下的其他文件中无须声明头文件,直接调用该变量。
C++:const修改的变量为常量。可以初始化数组。
1、全局const - 和C语言全局const结论一致。
2、局部const
#include <iostream>
#include <string>
using namespace std;
int main()
{
// C++中,const修饰的局部变量,该变量值以键值对的形式存放在符号表中。
const int var = 100;
// var = 200; // 直接修改一定不成功;
// C++中,int *p = (int*)&var的含义:先创建一个临时变量存放var的值,
// 即int tmp = var,再对tmp取地址存放在指针p中,因此通过指针修改
// 的是临时变量的值,而对var没有影响。
int* p = (int*)&var;
*p = 200;
printf("var = %d\n", var); // var = 100.可以运行,但修改不成功。
int arr[var]; C++中,const修改的变量为常量,可以用于初始化数组。
return 0;
}
3、const修饰的全局变量默认是内部链接属性,即只能在本文件中使用该变量,若在其他文件中使用该变量,编译器会报无法解析的外部命令错误。
若要在外部文件中使用该变量,须用关键字extern修饰该变量以提高其作用域。
七、const内存分配
1、对const修饰的变量取地址时,会分配临时内存,但不可修改该变量值;
2、const前加extern关键字后,会分配地址,可通过间接修改方式修改该变量值;
3、使用变量来初始化const修饰的变量,会分配内存,可通过间接修改方式修改该变量值;
int main()
{
int a = 10;
const int var = a;
int* p = (int*)&var;
*p = 20;
cout<<"var = "<<var<<endl;
return 0;
}
4、使用自定义类型数据来初始化const修饰的变量,会分配内存,可通过间接修改方式修改该变量值;
struct Student
{
string name;
int age;
}
int main(void)
{
const Student s = {"zhangsan", 10};
//s.name = "Lisi";
//s.age = 20;
Student* p = (Student*)&s;
p->name = "Lisi";
p->age = 20;
cout<<"Name: "<<s.name<<", Age: "<<s.age<<endl;
}
八、const与define
尽量使用const来替代define.
1、define定义的宏常量,没有数据类型;
2、宏常量不重视作用域。