C++---day02
目录:
1. C的提高 1-131P 时间七天
2. C++的基础 132-286P 时间八天
3. C++的提高 287-378P 时间五天
4. C/C++的数据结构 379-482P 时间五天
5. C/C++的设计模式基础 483-540P 时间三天
视频资料:https://www.bilibili.com/video/av27904891?from=search&seid=10891514449061956870
P141 实用性加强--register增强--检测性增强
“实用性”增加
#include "iostream" using namespace std; //C语言中的变量都必须在作用域开始的位置定义!! //C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。 int main11() { int i = 0; printf("ddd"); int k; system("pause"); return 0; }
register关键字增强
register关键字 请求编译器让变量a直接放在寄存器里面,速度快
在c语言中 register修饰的变量不能取地址
但是在c++里面做了内容
1、register关键字的变化
register关键字请求“编译器”将局部变量存储于寄存器中
C语言中无法取得register变量地址
在C++中依然支持register关键字
C++编译器有自己的优化方式,不使用register也可能做优化
C++中可以取得register变量的地址
2、C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。
3、早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充。
变量检测增强
在C语言中,重复定义多个同名的全局变量是合法的
在C++中,不允许定义多个同名的全局变量
C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上
int g_var; int g_var = 1;
C++直接拒绝这种二义性的做法。
P142 struct关键字类型增强
struct类型的加强:
C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型
C++中的struct是一个新类型的定义声明
#include "iostream" using namespace std; //struct关键字和class关键字完成的功能是一致的 struct Student { char name[100]; int age; }; int main(int argc, char *argv[]) { Student s1 = {"wang", 1}; Student s2 = {"wang2", 2}; return 0; }
P143 C++类型检查增强
C++中所有的变量和函数都必须有类型
C语言中的默认类型在C++中是不合法的
C++中,报错1>text.cpp(19): error C2660: “g”: 函数不接受 5 个参数
#include "iostream" using namespace std; int f(int i) { printf("i = %d\n", i); } int g() { return 5; } int main(int argc, char *argv[]) { f(10); printf("g() = %d\n", g(1, 2, 3, 4, 5));
getchar();
return 0;
}
C中不报错
f(i) { printf("i = %d\n", i); } g() { return 5; } int main(int argc, char *argv[]) { f(10); printf("g() = %d\n", g(1, 2, 3, 4, 5)); getchar(); return 0; }
总结:
在C语言中
int f( );表示返回值为int,接受任意参数的函数
int f(void);表示返回值为int的无参函数
在C++中
int f( );和int f(void)具有相同的意义,都表示返回值为int的无参函数
C++更加强调类型,任意的程序元素都必须显示指明类型
P144 新增数据类型Bool类型
C++中的布尔类型
C++在C语言的基本类型系统之上增加了bool
C++中的bool可取的值只有true和false
理论上bool只占用一个字节,
如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现
true代表真值,编译器内部用1来表示
false代表非真值,编译器内部用0来表示
bool类型只有true(非0)和false(0)两个值
C++编译器会在赋值时将非0值转换为true,0值转换为false
#include "iostream" using namespace std; void main() { bool b1=true;//告诉C++编译器分配1个字节的内存 cout<<"sizeof(bool)"<<sizeof(bool)<<endl; //bool变量 1或者0 b1=10; cout<<"b1:"<<b1<<endl; b1=-10; cout<<"b1:"<<b1<<endl; b1=0; cout<<"b1:"<<b1<<endl; system("pause"); return; }
输出结果:
P146 C++中的三目运算符
C中
#include<stdio.h> //在c语言中表达式的运算结果放在寄存器中 //表达式的返回值是一个数 //在C++中表达式返回的是变量的本身 int main() { int a = 10; int b = 20; //返回一个最小数 并且给最小数赋值成3 //三目运算符是一个表达式 ,表达式不可能做左值 (a < b ? a : b )= 30; printf("a = %d, b = %d\n", a, b); system("pause"); return 0; }
C++中
int main() { int a = 10; int b = 20; //返回一个最小数 并且给最小数赋值成3 //三目运算符是一个表达式 ,表达式不可能做左值 (a < b ? a : b )= 30; printf("a = %d, b = %d\n", a, b); system("pause"); return 0; }
结论
1)C语言返回变量的值 C++语言是返回变量本身
C语言中的三目运算符返回的是变量值,不能作为左值使用
C++中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方
2)注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用
(a < b ? 1 : b )= 30;
3)C语言如何支持类似C++的特性呢?
====>当左值的条件:要有内存空间;C++编译器帮助程序员取了一个地址而已
P147 const基础和const符号表机制探究
C中
//c语言中的const是冒牌货 void main() { const int a=10; int *p=NULL; p=(int *)&a; *p=20;//间接赋值 printf("a:%d\n",a); }
输出结果:a:20
C++中
//C++语言中const是一个真正的常量 int main() { const int a=10; int *p=NULL; p=(int *)&a; *p=20;//间接赋值 printf("a:%d\n",a); system("pause"); return 0; }
输出结果:a:10
解释
c++编译器对const常量的处理
当碰见常量声明时,在符号表中放入常量
问题:如何解释取地址
编译过程中若发现使用常量则直接以符号表中的值替换
编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)
结论
C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量
可能分配存储空间,也可能不分配存储空间
当const常量为全局,并且需要在其它文件中使用
当使用&操作符取const常量的地址
const分配内存的时机 编译器编译期间
P148 const和#define的对比
const定义的变量由编译器处理,提供类型检查和作用域检查
void fun1() { #define a 10 const int b = 20; //#undef a # undef } void fun2() { printf("a = %d\n", a); //printf("b = %d\n", b); } int main() { fun1(); fun2(); system("pause"); return 0; }
P149 引用的基础知识(定义和函数参数)
1、引用(普通引用)
a) 在C++中新增加了引用的概念
b) 引用可以看作一个已定义变量的别名
c) 引用的语法:Type& name = var;
d) 引用做函数参数那?(引用作为函数参数声明时不进行初始化)
//1. 引用的概念 void main() { int a=10; //引用的语法:Type& name = var; int &b=a; b=100; //相当于把a修改成100 printf("b:%d\n",b); printf("a:%d\n",a); a=200; printf("b:%d\n",b); printf("a:%d\n",a); system("pause"); }
输出结果:
2 、引用是C++的概念
//基础类型的引用 void myswap(int a,int b) { int c=0; c=a; a=b; b=c; } void myswap02(int *a,int *b) { int c=0; c=*a; *a=*b; *b=c; } //引用作为函数参数声明不进行初始化 void myswap03(int &a,int &b) { int c=0; c=a; a=b; b=c; } void main() { int x,y; x=10; y=20; myswap(x,y); printf("x:%d,y:%d\n",x,y); myswap02(&x,&y); printf("x:%d,y:%d\n",x,y); //a就是x的别名 b就是y的别名 myswap03(x,y); printf("x:%d,y:%d\n",x,y); //int &c;//普通引用必须要初始化 system("pause"); }
P150 复杂数据类型引用做函数参数
//复杂数据类型的引用 struct Teacher { char name[64]; int age; }; void printfT(Teacher *pT) { cout<<pT->age<<endl; } //pT是t1的别名,相当于修改了t1 void printfT2(Teacher &pT) { //cout<<pT.age<<endl; pT.age=33; } //pT和t1是两个不同的变量 void printfT3(Teacher pT) { cout<<pT.age<<endl; pT.age=45;//只会修改pT变量,不会修改t1变量 } void main() { Teacher t1; t1.age=35; printfT(&t1); printfT2(t1);//pT是t1的别名 printfT3(t1);//pT是形参,t1copy一份数据给pT pT=t1 printf("t1.age:%d\n",t1.age); system("pause"); }