一、c++的语法检查增强
c++的全局变量检测增强。
c++中所有的变量和函数必须有类型。
c++中不同类型的变量不能直接赋值,需要相应的强制类型转换。
二、c++对结构体的增强
c语言中定义结构体变量需要加struct关键字,c++中不需要
c语言中的结构体只能定义成员变量,不能定义成员函数;c++中的结构体既可以定义成员变量,也可以定义成员函数。
c语言:
struct stu
{
int num;
char name[32];
}
void test01()
{
//c语言中必须加struct
struct stu person = {10, "Bob"}
}
c++:
struct stu
{
int num;
char name[32];
//c++中允许在结构体中定义成员函数
void func(void)
{
cout << "This is Func!" << endl;
}
}
void test01()
{
//c++中不需要加struct
stu person = {10, "Bob"}
//结构体中成员函数调用
person.func();
}
三、c++新增bool类型
标准c++的bool类型有两种内设的常量true和false,bool类型中只有true(1值)和false(0值),bool类型占一个字节,给bool类型赋值时,非0值会自动转化为true,0值则自动转化为false。
四、三目运算符增强
c语言中三目运算表达式的返回值为数据值,是右值,不能赋值。
void test01()
{
int a = 10;
int b = 20;
printf("c中:%d\n", a>b?a:b); //值为20
//a>b?a:b = 100; //err 右值不能被赋值
}
c++中三目运算表达式的返回值为变量本身,是左值,可以赋值。
void test01()
{
int a = 10;
int b = 20;
cout << "c++中:" << (a>b?a:b) << endl;
//a>b?a:b整体结果为变量本身,是左值
a>b?a:b = 100; //100
}
注意【左值和右值的概念】:能被赋值的是左值,不能被赋值的是右值。在c++中可以放在操作符左边的是左值,可以放在操作符右面的是右值。有些变量既可以当左值,也可以当右值。左值为Lvalue,L代表Location,表示内存可以寻址,能够被赋值;右值为Rvalue,R代表Read,表示只读。例如:int tmp = 10; tmp在内存中有地址,10没有,因此tmp为左值,10为右值。
五、c++中的const
c语言中的const
c语言中的const修饰全局变量,默认是外部链接。
fun.c
//c语言中的const修饰全局变量,默认是外部连接的
//外部连接:其他源文件可以使用
const int num = 10;
main.c
#include <stdio.h>
int main(void)
{
extern const int num; //声明
printf("num = %d\n", num); //const修饰全局变量num,变量名只读,内存空间在文字常量区(只读)
//不能通过num的地址修改变量内容
const int data = 100; //const修饰局部变量data,变量名只读,内存空间在栈区(可读可写)存储,
//可以通过data地址间接更改空间内容
int *p = (int *)&data;
*p = 2000;
printf("data = %d\n", data);
return 0;
}
c语言中const修饰全局变量num,变量名只读,内存空间在文字常量区(只读),不能通过num地址修改空间的内容;const修饰局部变量data,变量名只读,内存空间在栈区(可读可写),可以通过data地址,间接的修改空间内容。
c++中的const
fun.cpp
//如果要将const修饰的全局变量用在其他源文件中,必须加extern将变量转换成外部连接
extern const int num = 100;
main.cpp
#include <iostream>
using namespace std;
// c++中const函数外修饰的变量作用于当前文件,默认为内部连接。
//c++中其他的标识符一般默认为外部连接
extern const int num; //声明
struct person{
int num;
char name[32]
}
int main()
{
//1、c++中 对于基础类型 系统不会给data开辟空间,而是把data放在符号表中
const int data = 1000;
cout << "data = " << data << endl;
int *p = (int *)&data;
*p = 2000;
cout << "data = " << data <<endl;
cout << "num = " << num << endl;
//2、以变量的形式 const修饰的变量 系统会开辟空间
int b = 100;
const int a = b;
p = (int *)&a;
*p = 3000;
cout << "*p = " <<*p<<endl;
cout << "a = " <<a<<endl;
//3、const 自定义数据类型(结构体、对象) 系统会开辟空间
const person per = {100, "Bob"};
cout <<"num = " << per.num <<", name = " << per.name << endl; //100 Bob
person *p1 = (person *)&per;
p1->num = 2000;
cout <<"num = " << per.num <<", name = " << per.name << endl; // 2000 Bob
return 0;
}
c++中const int data = 10; //data放入符号表内,不开辟存储空间;
如果对data进行取地址,系统才会给data开辟内存空间;
const int a = b; //b为变量名,系统将直接给a开辟内存空间,不放入符号表;
const修饰自定义数据时,系统会给自定义数据开辟内存空间。
六、尽量用const替换#define
const 和#define的区别:
const有类型,可以进行编译器类型安全检查。#define无类型,不可进行类型检查;
const有作用域,而#define不重视作用域,默认定义处到文件结尾。如果定义在指定作用域下有效的常量,那么#define就不能用。
宏没有类型,而const有
#define MAX 1024
const short my_max = 1024;
void func(short i)
{
cout << "short函数" << endl;
}
void func(int i)
{
cout << "int 函数" << endl;
}
void test01()
{
func(MAX); //int 函数
func(my_max);//short函数
}
宏作用域是整个文件,const的作用域以定义情况决定
void func(void)
{
const int my_num = 10;//作用范围为当前复合语句
#define MAX 1024 //作用范围从当前位置到文件结尾
}
void test01()
{
//cout << "my_num = " << my_num << endl; //err
cout << "MAX = " << MAX << endl;// AC
}
宏不能作为命名空间的成员,const可以
namespace A{
//const 可以作为成员变量
const int num = 10;
//MAX属于文件,不属于A
#define MAX 1024
}
void test01()
{
cout << "num = " << A::num << endl;
cout << "MAX = " << MAX <<endl;
}