当前位置: 首页 > news >正文

网站建设为什么这么贵seo智能优化系统

网站建设为什么这么贵,seo智能优化系统,怎么做仲博注册网站,山东青岛疫情最新情况C的关键字 C总计63个关键字&#xff0c;C语言32个关键字 命名空间 我们C的就是建立在C语言之上&#xff0c;但是是高于C语言的&#xff0c;将C语言的不足都弥补上了&#xff0c;而命名空间就是为了弥补C语言的不足。 看一下这个例子。在C语言中会报错 #include<stdio.h>…

C++的关键字

C++总计63个关键字,C语言32个关键字
在这里插入图片描述

命名空间

我们C++的就是建立在C语言之上,但是是高于C语言的,将C语言的不足都弥补上了,而命名空间就是为了弥补C语言的不足。

看一下这个例子。在C语言中会报错

#include<stdio.h>
#include<stdlib.h>int rand = 10;int main()
{printf("%d ", rand);return 0;
}

在这里插入图片描述

原因就是在我们#include<stdlib.h>中,定义了rand ,但是我们自己也定义了一个全局变量rand,这样就重定义了,C语言无法解决这个问题。
所以我们这是C++,为了解决这个问题,就引用了命名空间的概念。

我们在C语言中,我们们接触的一共有两个,
一个是全局域,一个是局部域。他们的使用,和生命周期不一样。
而在这两个域中,我们可以声明同一个名字的变量,这是可以的。

但是我们想在局部作用域中,找命名相同的全局域的东西可以吗?
答案是可以的,这是就要用到我们的域作用符 ::,前面的空格就表示全局域。
看下面代码

#include<stdio.h>
#include<stdlib.h>int a = 10;void f1()
{int a = 0;printf("%d\n", a);printf("%d\n", ::a);
}int main()
{f1();return 0;
}

在这里插入图片描述

命名空间定义了什们?
命名空间域,只影响使用,不影响生命周期。
这时就需要一个关键字—namespace
命名空间怎么用?
当我们的命名存在冲突的时候,将各自的内容用namespace定义的域包括起来(这时我们自己定义这个域名),当我们要找的时候就用就域操作符::,找到我们的域名,就可以找到我们的命名冲突的东西。请看下列例子。
namespace List
{struct Node{struct QNode* next;struct QNode* prev;int val;};
}namespace Queue
{struct Node{struct QNode* next;int val;};}int main()
{//f1();struct Queue::Node node1;struct List::Node node2;return 0;
}

注意我们的命名空间,可以嵌套。

使用方法

1.指定命名空间访问。

每次使用的时候,我们都使用域作用符表明他的域

namespace Queue
{struct Node{struct QNode* next;int val;};struct QueueNode{struct Node* head;struct Node* tail;};void QueueInit(struct QueueNode* q){}void QueuePush(struct QueueNode* q,int x){}
}int main()
{struct Queue::QueueNode q;Queue::QueueInit(&q);Queue::QueuePush(&q,1);Queue::QueuePush(&q,2);
}

2.全局展开(一般情况,不建议全局展开)

我们用一次展开一次,太繁琐了,我们怎样可以简单一点呢?

就是用全局展开,
代码为using namespace + 域名

namespace Queue
{struct Node{struct QNode* next;int val;};struct QueueNode{struct Node* head;struct Node* tail;};void QueueInit(struct QueueNode* q){}void QueuePush(struct QueueNode* q,int x){}
}using namespace Queue;int main()
{struct QueueNode q;QueueInit(&q);QueuePush(&q,1);QueuePush(&q,2);
}

所以我们写C++,代码的时候,
我们要加上一句using namespace std,将我们库文件的东西全局展开。
但是这种方法不太好,将我们好不容易建立的库,就有展开了,相当于没有命名空间了
所以我们以后进公司写项目,禁止这样写代码,但是我们在前期学习阶段,我们是可以这样的,因为这样很方便。

3.部分展开

就是将常用的展开。具体看下面的例子

#include<iostream>//常用的展开
using std::cout;
using std::endl;int main()
{cout << "1111" << endl;cout << "1111" << endl;cout << "1111" << endl;cout << "1111" << endl;int i = 0;std::cin >> i;
}

cin和cout的理解

其实就是流,输入流,和输出流。
我们可以简单的认为,
cout相当于printf
cin相当于scanf

他们的优势
自动识别类型。
不用想我们的printfscanf需要指定类型,%d,%f,但是我这个就不用,他自动识别类型。
#include<iostream>
using namespace std;int main()
{cout << "hello world" << endl;cout << "hello world" << '\n';int n;double* a = (double*)malloc(sizeof(double) * n);if (a == NULL){perror("malloc fail");exit(-1);}cin >> n;for (int i = 0; i < n; i++){cin >> a[i];}for (int i = 0; i < n; i++){cout << a[i] << endl;}
}

在这里插入图片描述

缺省参数

也是为了弥补c语言的缺陷。

这是通过函数使用的,在c语言中,当我们的函数有参数的时候,我们在用这个函数的时候,我们必须传这个参数。
而缺省参数的作用,就是我们在函数传参的时候,可以不用传参数。在我们不传参数的时候,就会把我们的默认参数传上。

void Func(int a = 0)
{cout << a << endl;
}int main()
{Func(1);Func();return 0;
}

在这里插入图片描述

多个缺省参数

//全缺省
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;cout << endl;}int main()
{Func(1, 2, 3);Func(1, 2);Func(1);Func();return 0;
}

在这里插入图片描述

注意:不可以跳着传,使用缺省值,必须从右往左连续使用
下列用法不可以,这是规定没有为什们
Fun( ,2, );
Fun( , , 3);

半缺省

注意:必须从右往左连续缺省,不能跳跃缺省

//这样是可以的
void Func(int a, int b = 10, int c = 20) {cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl; }
int main()
{Func(1, 2, 3);Func(1, 2);Func(1);return 0;
}
//这样是错误的,完全不可以
void Func(int a = 10, int b , int c = 20) {cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl; }
注意
缺省参数不能在函数声明和定义中同时出现。
推荐在声明的时候给我们的缺省参数)
如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该 用那个缺省值。
	void Func(int a = 10); void Func(int a = 20) {}

函数重载

其实这也是为了解决c语言的缺陷,当一个函数同名的时候,我们就会重定义。

可能你会想,为什们要函数重载,函数本来就不能同名呀。
那你大错特错了,我们看完下面这个例子就知道了。

函数重载的定义
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

函数返回值不同,不能构成函数重载。
是因为我们调用的时候可以不接受返回值,但是和没有返回值的函数无法区分,所以才不可以。

参数类型不同

// 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;
}
int main()
{Add(1, 2);Add(1.1, 2.2);return 0;
}

参数个数不同

// 2、参数个数不同 
void f()
{cout << "f()" << endl;
}
void f(int a) 
{cout << "f(int a)" << endl;
}

参数顺序不同

// 3、参数类型顺序不同 
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;
}

编译器怎么分辨这些相同名字的函数呢

  1. 实际项目通常是由多个头文件和多个源文件构成,我们知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标
    文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么怎么办呢?
  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
  3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的 函数名修饰规则。
  4. 由于Windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,下面我们看g++演示了这个修饰后的名字。
  5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度 +函数名+类型首字母】。

引用

什们是引用?(就是取别名)
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
比如:你有大名和小名,但那都是你,而引用就相当于这个。
引用怎么写?
就是类型后面加一个&。
要区别赋值和引用。
在这里插入图片描述

那我们用一下&,写一下我们的交换函数,就不用再传指针了。

//输出型参数
//形参的改变要影响实参。
void Swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}int main()
{int i = 10;int j = 20;Swap(i, j);printf("i=%d\n", i);printf("j=%d\n", j);return 0;
}

引用特征

  1. 引用必须在定义的时候初始化。
  2. 一个变量可以有多个引用

引用做返回值

我们先看一个场景,看完下面这个场景,我问一个问题,

在函数的返回值中我们是将函数中的n返回了吗?
答案是否定的,我们n是一个局部变量,他的生命周期就是在函数中,一但出了函数,那么它就会被销毁。
那么有的同学就会想:他是怎么传出来的呢?
其实编译器会将我们的n拷贝一个临时变量(临时变量具有常性),然后用这个临时变量将我们的n传给我们的ret

同时我们想优化一下他,我们也是不可以的,我们没有办法优化,但是我们看第二个例子

int  count()
{int n = 0;n++;return n;
}
int main()
{int ret = count();return 0;
}

第二个例子不太一样,我们的n存放在静态区,当函数被销毁的时候我们的n还在,但是这是有的同学会问,那么它传返回值是直接用n传吗?
答案并不是,编译器并不能分辨他们是哪一种,只会进行他的操作,跟上面一样还是产生一个n的临时拷贝,用的这个临时拷贝传个ret

怎么优化?
我们想要优化一下这个,怎么优化?我们学习了引用,就是产生一个别名,我们可以通过改变别名来改变这个东西。
因为我们这里的n并不会被销毁,如果我们在返回的时候用引用。
这时我们还会像上面的操作一样产生一个临时变量,但是这个临时变量就不是我们的临时拷贝而是我们n的一个别名,我们如果想改变n,我们就可以通过改变返回值改变我们的n
int  count()
{static int n = 0;n++;return n;
}
int main()
{int ret = count();return 0;
}

这就是引用返回。

int&  count()
{static int n = 0;n++;return n;
}
int main()
{int ret = count();return 0;
}

什们场景下可以使用引用返回?

: 大家可能想到的是我们的静态变量,全局变量。结构体。
其实这些东西用一句话来说就是出了函数作用域,不被销毁的变量就可以。

引用返回的作用

通过上面的介绍我们知道了什们是引用返回,但是我们有这个有什么作用?我们什们情况下会用到这个。
那就看看下面这个例子。

#include<assert.h>
#define N 10typedef struct Array
{int a[N];int size;
}AY;//因为这个结构体在我们函数销毁完,我们还在所以可以用引用返回
int& PosAY(AY& ay, int i)
{assert(i < N);return ay.a[i];
}
int main()
{AY ay;//修改返回值for (int i = 0; i < N; i++){PosAY(ay, i) = i * 10;}//打印出来验证for (int i = 0; i < N; i++){cout << PosAY(ay, i) << " ";}return 0;
}
作用一
减少拷贝。
我们如果不用引用返回,那么我们在返回的时候我们要创建一个临时变量,将我们需要传的数据拷贝给临时变量。而我们的引用返回,直接将这个临时变量当作他的别名。
作用二
调用者可以修改返回对象
既然临时变量已经是我们要传的数据的别名,那么我们就可以修改返回对象来修改我们的数据。

下面我们在看一个例子

int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :" << ret << endl;cout << "Add(1, 2) is :" << ret << endl;return 0;
}

运行结果:
在这里插入图片描述

这是一个错误的程序,我们这个函数,在我们出去了这个函数,函数就会被销毁,而我们c是一个局部变量,也就说明c在出来函数也被销毁。
但是我们在传返回值的时候我们传的是引用返回,我们传的是别名,这时ret就是别名,但是已经销毁了,我们的别名就已经没有意义。

有的同学就问,那我们第一次是7呢,是因为在vs编译器下,函数销毁并没有清理空间,我们访问可以找到。但是第二次已经处理了,所以我们就是随机值了。

常引用

我们先看例子。

int main()
{int a = 1;int& b = a;const int c = 2;//错误//int& d = c;
}

我们的指针和引用,在进行赋值和初始化,权限可以缩小,但是权限不能放大。
就是我们上面对于c来说,cconst修饰,是一个不可修改的变量。
但是呢我们用d引用c,尽然可以让d修改,进而改变c,这显然是不合法的。这时我们就能理解为什们权限不能放大。但是权限可以平移。

解决方法,就是在引用的时候也变成被const修饰的引用,让他变得不可修改。const int& d = c;

因为临时变量具有常性,大家看一下下面这个例子

int count()
{static int n = 0;n++;return n;
}
int main()
{int& ret = count();return 0;
}

上面这个代码大家千万不要以为这样可以,我们通过上面的讲解,并不是直接将我们的n返回,而是将我们的n拷贝给我们的临时变量。将其引用给ret涉及到权限的放大,这时万万不行的,所以我们的可以将ret也设置为常性。const int& ret = count();这样就可以了。

我们再看一个代码。

int main()
{int i = 10;//错误//double& dd = i;const double& d = i;return 0;
}

为什们第一个不可以,但是第二个可以呢?
原因就是我们在进行类型转换的时候,我们会产生一个临时变量,(为什们会产生临时变量呢?我们再传的时候并不是将i直接传给d,并不能改变i,而是产生一个临时变量,将他改变,然后再赋值在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。给d。)又因为我们的临时变量具有常性,我们就必须用const修饰。

引用和指针的区别

语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. sizeof中含义不同引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

内联函数

C++用const和枚举替换宏常量
C++用inline去替代宏函数

宏缺点
1.不能调试
2.没有类型安全的检查
3.有些常见很复杂,很容易函数,不容易掌握。
宏优点
  1. 增强代码的复用性。
  2. 提高性能。

内联函数既包括了宏的优点,也几乎去除了宏的缺点。
看一个例子感受内联函数的使用。
其实就是还是正常写我们的函数,再其前面加上inline,在编译阶段,会用函数体替换函数调用。

inline int Add(int x, int y)
{int z = x + y;return z;
}int main()
{int ret = Add(1, 2);cout << ret << endl;return 0;
}

内联函数的特型

1. inline是一种以空间换时间(空间指可执行程序)的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。
2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

auto关键字

auto的作用
简化代码,自动识别类型。具体看下面代码
int main()
{int a = 0;auto b = a;auto c = &a;//typeid能看他是什们类型cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;
}

在这里插入图片描述

	auto b = a;auto c = &a;//其实下面这个跟上面这个没有区别//就是将限定死d是指针auto* d = &a;auto& f = a;

auto在同一行定义多个变量

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

void TestAuto() 
{auto a = 1, b = 2;auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同 
}

auto不能推导的场景

  1. auto不能作为函数的参数
    在这里插入图片描述
  2. auto不能直接用来声明数组
    在这里插入图片描述

范围for–语法糖

先看例子

int main()
{int a[] = { 1,2,3,4,5,5 };//我们平常遍历一边数组,我们用的就是for循环for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++){cout << a[i] << " ";}cout << endl;//那我们用语法糖//其实就是自己自动依次取数组中数据赋值给n对象,自动判定结束//for(int n : a)for (auto n : a){n *= 2;cout << n << " ";}cout << endl;
}

范围for只是自动依次取数组中数据赋值给n对象,自动判定结束
并不会改变数组的内容,他只是赋值。
如果想要改变数组的内容,我们就用引用,问题就可以很好的解决。

在这里插入代码片

指针空值nullptr

在C语言中,NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus 
#define NULL    0 
#else
#define NULL    ((void *)0) 
#endif
#endif

可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何 种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦
比如下面的代码,
结果是这样的
在这里插入图片描述

void f(int) 
{cout<<"f(int)"<<endl; 
}
void f(int*) 
{cout<<"f(int*)"<<endl; 
}
int main()
{f(0);f(NULL);f((int*)NULL); return 0;
}

所以C++使用一个关键字nullptr来解决这个麻烦

注意
  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的.
  1. 在C++11中,sizeof(nullptr)sizeof((void*)0)所占的字节数相同。
  1. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr
http://www.dinnco.com/news/32437.html

相关文章:

  • 中企动力网站推广移动端优化
  • 三门峡网站制作上海app网络推广公司
  • 网站建设客户需求表厨师培训
  • 做高大上分析的网站百度sem运营
  • 网站的按钮怎么做杭州做百度推广的公司
  • 大型网站技术架构核心原理与案例分析站长seo软件
  • 深圳鼎诚网站建设国外黄冈网站推广软件
  • 外贸独立网站制作营销型网站更受用户欢迎的原因是
  • 开发一个简单的系统杭州网站推广与优化
  • 自定义功能的网站今日新闻热点大事件
  • 做微整去那个网站找好的医院百度电脑版下载安装
  • 输入网站查看空间浙江网络科技有限公司
  • 网站建设存在的问题有哪些多少关键词排名优化软件
  • 刚做的网站怎么在百度搜到谷歌网站网址
  • 网页开发和app开发哪个难windows11优化大师
  • 服装工厂做网站的好处榆林百度seo
  • 深圳微信网站建设北京百度快速排名
  • 给别人做设计的网站百度经验怎么赚钱
  • b2c行业网站系统企业网站优化关键词
  • 商标可以做网站吗沈阳seo排名收费
  • 胶州网站设计公司网页制作软件推荐
  • 个人注册的网站可以做公司宣传用吗seo网络营销技术
  • 企业做网站的发票怎样入账福建搜索引擎优化
  • 营销型网站建设实战感想小程序开发公司前十名
  • 北京市网站公司网站常用的网络营销推广方法有哪些
  • 银川市网站制作公司排行榜前十名
  • 信誉好的企业网站开发百度推广工作怎么样
  • 17zwd一起做网站官网苏州seo报价
  • 做好史志网站建设可以发外链的论坛有哪些
  • 唐山做网站公司费用广州seo软件