还是唐老师的视频,还是老样子,既然看了学了,就做点笔记做点精简和总结,
以后有用得到的地方,也方便查找。本文章只有比较C与C++ 有联系的不同之处,并没有C++独有的内容。
..添加目录栏目 2021/9/17
int c = 0;
for(int i=1; i<=3; i++)
{
for(int j=1; j<=3; j++)
{
c += i * j;
}
}
C语言中多个同名的全局变量最终会被连接到全局数据区的同一个地址空间上,C++直接拒绝这种二义性的做法
bool 是C++ 中的基本数据类型,可以定义bool类型的 全局变量,常量,指针,数组
int main()
{
const int c = 0;
int* p = (int*)&c;
*p = 5;
printf("c = %d\n", c);//c语言中可以改变 c= 5,C++中 c= 0
printf("*p = %d\n", *p);
printf("End...\n");
return 0;
}
void f()
{
#define a 3
const int b = 4;
}
void g()
{
printf("a = %d\n", a); //C++编译不会报错,这个地方编译器看到的a 是3
printf("b = %d\n", b); //C++编译报错,编译器发现b作用域不在这里
}
编译器压根不知道 宏 的存在,预处理器直接进行了文本替换
#include
int main()
{
const int x = 1;
const int& rx = x;//rx代表一个只读变量,这个变量所对应的内存空间是编译器为x常量分配的空间
int& nrx = const_cast<int&>(rx);//nrx 对应的空间 和 rx一直,但是他没有只读属性
nrx = 5;
printf("x = %d\n", x);
printf("rx = %d\n", rx);
printf("nrx = %d\n", nrx);
printf("&x = %p\n", &x);
printf("&rx = %p\n", &rx);
printf("&nrx = %p\n", &nrx);
volatile const int y = 2; //不是真正意义上的常量
int* p = const_cast<int*>(&y); //将y的地址的只读属性去掉
*p = 6;
printf("y = %d\n", y);
printf("p = %p\n", p);
const int z = y; //编译不确定z的值,所以z是只读变量
p = const_cast<int*>(&z);
*p = 7;
printf("z = %d\n", z);
printf("p = %p\n", p);
char c = 'c';
char& rc = c; // rc代表 c
const int& trc = c;//const引用他的类型不同的话,他会得到一个新的只读变量 trc
rc = 'a';
printf("c = %c\n", c);
printf("rc = %c\n", rc);
printf("trc = %c\n", trc);
return 0;
}
void swap(int& a, int& b){
int t = a;
a = b;
b = t;
}
int a = 4;
const int& b = a;
int* p =(int*)&b;
b = 5; //Error, 只读变量
*p = 5; //OK. 修改变量 a 的值
#include
int main()
{
const int& b = 1;
int* p = (int*)&b;
printf("b = %d\n", b);
printf("*p = %d\n", *p);
printf("p =%p\n", p);
// b = 5; //ERROR
*p = 5;
printf("b = %d\n", b);
printf("*p = %d\n", *p);
printf("p =%p\n", p);
return 0;
}
#include
int a = 1;
struct SV
{
int& x;
int& y;
int& z;
};
int main()
{
int b = 2;
int* pc = new int(3);
SV sv = {a, b, *pc};
int& array[] = {a, b, *pc};//&array[1] - &array[0] = 应该是4,数组\
所以在C++里面不支持引用数组
printf("&sv.x= %p\n",&sv.x);
printf("&sv.y= %p\n",&sv.y);
printf("&sv.z= %p\n",&sv.z);
delete pc;
return 0;
}
inline int func(int a, int b)
{
return a < b ? a : b;
}
_attribute_((always_inline)) //g++
_forceinline //MSVC
C++ 中 inline 内联编译的限制:
在C++中可以为函数提供 站位参数
int func(int x, int){
return x;
}
//...
func(1,2); //ok
函数占位参数 为了 兼容C语言程序 中可能出现的不规范写法,看下面的例子:
void func(int = 0, int = 0){}
int main(int argc, char *argv[])
{
func();
func(1,2);
return 0;
}
函数重载(Function Overload)
当 函数默认参数 遇上 函数重载会发生什么?
#include
int func(int a, int b, int c = 0){
return a * b * c;
}
int func(int a, int b){
return a + b;
}
int main(int argc, char *argv[])
{
int c = func(1, 2);//编译器会报错,他不知道该调用什么 ERROR
return 0;
}
函数重载是由 函数名 和 参数列表 决定的!!!
#include
extern "C"
{
#include "add.h"
}
int main()
{
int c = add(1, 2);
...
}
专用关键字 new
p = new int[10]; //p指向的这段内存空间至少为 40字节,不能保证要多少给多少,可以保证至少这么多
#include
int main()
{
int* pi = new int(1);
int* pa = new int[1];
float* pf = new float(2.0f);
char* pc = new char('c');
printf("*pi = %d\n",*pi);
printf("*pa = %d\n",*pa);
printf("*pf = %f\n",*pf);
printf("*pc = %c\n",*pc);
printf("pi = %p\n",pi);
printf("pa = %p\n",pa);
printf("pc = %p\n",pc);
delete pi;
delete pa;
delete pf;
delete pc;
return 0;
}
在C语言中,所有的全局标识符共享同一个作用域,在大工程中标识符之间可能发生冲突
C++中提出了命名空间的概念
//C++ 命名空间的定义
namespace Name
{
namespace Internal
{
}
}
C++命名空间的使用:
#include
namespace First
{
int i = 0;
}
namespace Second
{
int i = 1;
namespace Internal
{
struct P
{
int x;
int y;
};
}
}
int main()
{
using namespace First;
using Second::Internal::P;
printf("First::i = %d\n",i);
printf("Second::i = %d\n",Second::i);
P p ={2, 3};
printf("p.x = %d\n",p.x);
printf("p.y = %d\n",p.y);
return 0;
}
C方式强制类型转换 过于粗暴(任意类型之间都可以进行转换),难于定位
#include
void static_cast_demo(){
int i = 0X12345;
char c = 'c';
int *pi = &i;
char* pc = &c;
c = static_cast<char>(i); //将i int类型转换成 char类型,OK
// pc = static_cast(pi);//整型指针 转换,Error
}
void const_cast_demo(){
const int& j = 1; //产生了一个只读变量
int& k = const_cast<int&>(j);//将 j 的只读属性去掉,变成普通变量,用k来修改这个变量j 的值
const int x = 2; //产生了一个常量
int& y = const_cast<int&>(x); // 这个去掉只读属性,但是x进入了符号表,编译器会为x分配了空间,\
得到的内存里面为这个常量分配空间,y就是这个空间的别名
// int z = const_cast(x);//const_cast只能用于引用 和指针转换, Error
k = 5;
printf("k = %d\n", k);
printf("j = %d\n", j);
y = 8;
printf("x = %d\n", x);
printf("y = %d\n", y);
printf("&x = %d\n", &x);
printf("&y = %d\n", &y);
}
void reinterpret_cast_demo(){
int i = 0;
char c = 'c';
int *pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);//OK
pi = reinterpret_cast<int*>(pc);
pi = reinterpret_cast<int*>(i);//将整形转换为指针,OK
// c = reinterpret_cast(i);//基本类型的转换,Error
}
void dynamic_cast_demo(){
int i = 0;
int* pi = &i;
// char * pc = dynamic_cast(pi);//类指针之间,还需要有虚函数
}
int main()
{
static_cast_demo();
const_cast_demo();
reinterpret_cast_demo();
dynamic_cast_demo();
return 0;
}