C++基础入门——语法详解篇(下)

news2024/12/25 9:07:05

文章目录

一、缺省参数

1、1 缺省参数的概念

1、2 缺省参数的分类

1、2、1 全部缺省

1、2、2 半缺省参数

二、引用

2、1 引用的概念

2、2 引用特征

2、3 引用的使用场景

2、3、1 引用做参数

 2、3、2 常引用

2、3、3 引用做返回值

 2、4 引用总结

三、内联函数

3、1 内联函数的引出

3、2 内联函数详解

3、2、1 内联函数的概念

3、2、2 内联函数的特性

四、auto关键字(C++11)

4、1 auto简介

4、2 auto的使用细节

4、2、1 auto与指针和引用结合起来使用

4、2、2 在同一行定义多个变量

4、3 auto不能推导的场景


🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️

👀 专栏:C++ 👀

💥 标题:C++基础语法 💥

 ❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️

  本篇文章解C++基础入门——语法篇(上)来讲述C++基础语法。学玩本篇文章就可以写出简单的C++程序了。

一、缺省参数

1、1 缺省参数的概念

  缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。具体我们可看如下例子:
void Func(int a = 0)
{
 cout<<a<<endl;
}
int main()
{
 Func(); // 没有传参时,使用参数的默认值
 Func(10); // 传参时,使用指定的实参
 
 return 0;
}

  下面为运行结果。我们看到第一个Func函数并没有传参,就默认输出了缺省参数0。 

1、2 缺省参数的分类

1、2、1 全部缺省

  全部缺省就是我们把形参全部给出缺省值。具体例子如下:

void Func(int a = 10, int b = 20, int c = 30)
{
 cout<<"a = "<<a<<endl;
 cout<<"b = "<<b<<endl;
 cout<<"c = "<<c<<endl;
}

   这种情况我们在调用函数时,可传参,也可选择不传参。但是当我们传的参数只有一个时,默认是从左往右赋值的。也就是先给到a,再给到b,最后给到c。那要是我们想只给a,c赋值且不给b赋值呢?这种情况是不被允许的。我们只能从左往右依次赋值。

1、2、2 半缺省参数

  我们先看具体实例:

void Func(int a, int b = 10, int c = 20)
{
 cout<<"a = "<<a<<endl;
 cout<<"b = "<<b<<endl;
 cout<<"c = "<<c<<endl;
}

   半缺省参数是由几点要注意的:

  1. 半缺省参数必须从右往左依次来给出缺省值,不能间隔着给;
  2. 如果函数的声明和定义分开,缺省值不能在函数声明和定义中同时出现;
  3. 如果函数的声明和定义分开,缺省值在函数的声明时给出即可;
  4. 缺省值必须是常量或者全局变量;
  5. C语言不支持(编译器不支持) 。

二、引用

2、1 引用的概念

  引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

  引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

  这里给大家举一个例子。我想每个人都有一个小名吧。比如,班级上有一个 高同学 ,我们通常喊他为 小高 。那高同学 和 小高是一个人吗?答案肯定是一个人。我们在这里可以把高同学想象成变量,小高 是高同学的引用,小高犯错等同于高同学犯错。

  我们这里再看一下引用的用法。类型& 引用变量名(对象名) = 引用实体。

void Test()
{
 int a = 10;
 int& ra = a;//<====定义引用类型
 
 printf("%p\n", &a);
 printf("%p\n", &ra);
}

   我们这里看到他们地址是相同的,也就是指向的同一块数据。

  注意:引用类型必须和引用实体同种类型的。

2、2 引用特征

  在使用引用时,我们需注意以下几点:

  1. 引用在定义时必须初始化;
  2. 一个变量可以有多个引用;
  3. 引用一旦引用一个实体,再不能引用其他实体。
  我们结合下面实例一起理解一下。
void TestRef()
{
 int a = 10;
 int b = 20;
 // int& ra; // 该条语句编译时会出错
 int& ra = a;
 int& rra = a;
 rra = b;  //把b的值赋给rra,不是b的别名
 printf("%p %p %p\n", &a, &ra, &rra); 
}

2、3 引用的使用场景

2、3、1 引用做参数

  引用做参数,虽然大部分情况指针都可完成,但是引用做参数还是比较方便且较为容易理解的,我们看一下实例:  

void Swap(int& left, int& right)
{
 int temp = left;
 left = right;
 right = temp;
}

  上述对两个值交换,我们不再使用指针,直接可以使用引用进行交换。引用做参数还有另一个优势,就是在数据量较大,且数据本身也较大的情况下,引用作为参数的小路就会有所提高。为什么呢?

  以值作为参数,在传参期间,函数不会直接传递实参,而是传递实参的一份临时的拷贝,因此用值作为参数,效率是非常低下的,尤其是当参数非常大时,效率就更低。
  我们可以统一下面代码进行比较就可看出。
#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void TestRefAndValue()
{
 A a;
 // 以值作为函数参数
 size_t begin1 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc1(a);
 size_t end1 = clock();
 // 以引用作为函数参数
 size_t begin2 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc2(a);
 size_t end2 = clock();
 // 分别计算两个函数运行结束后的时间
 cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
 cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

  运行结果如下:

 2、3、2 常引用

  我们先看如下代码:

const int a = 10;
int& ra = a;

  大家感觉上述的代码有问题吗?答案是有问题的。a 是一个常数,只有读的权限,不能对其修改。而 ra 是对 a 的引用,这里相当于对 a 来说权限放大了。如果正确的话,ra 可以修改 a 的值,但事实上是不可以的。我们应在 ra 前加上const。

   我们再来看一段代码:

double d = 12.34;
 int& rd = d;

  上面的代码正确吗?似乎因并没有错。但好像也错了,也为类型不同。首先上述的代码是有错的。但根本原因并不是类型不同。根本原因在于中间生成了一个临时变量,而临时变量具有常性

   如下代码就正确了:

 double d = 12.34;
 const int& rd = d;

2、3、3 引用做返回值

   引用做返回值时,有会有一些坑。我们可以看如下例子:

int& Count()
{
 int n = 0;
 n++;
 // ...
 return n;
}

int main()
{
 int ret = Count();
 printf("%d ", ret ); 
 return 0;
}

  表面上似乎并没有什么错误,但实际上已经相当于访问野指针了。Count函数中n出了该函数就销毁了,变量 n 的那段地址空间的使用权限被收回了。Count函数的栈帧也会销毁。有的编译器在栈桢销毁时会清楚数据,有的并不会。在这里可能侥幸打印出正确数据,但确实是错误的。

   函数的传值返回和传引用返回有什么区别呢?我们先来看一下传值返回:

int test()
{
 static int a=0;
 return a;
}

int main()
{
 int& b=test();
 return 0;
}

  我们知道,当a为局部变量时(也就是上述代码中的 a 不加 static ),传值返回时,会把 a 拷贝给一个临时变量,再把临时变量的值赋给 test() 函数。注意:此时的临时变量在main函数中。那要是上述情况呢?同样与局部变量 a 的情况一样,把 a 拷贝给一个临时变量,再把临时变量的值赋给 test() 函数。编译器并不会在这里判断 a 出了作用域是否销毁,传值返回统一把值拷贝给一个临时变量,再把临时变量的值赋给函数

  我们上面了解到了临时变量具有常性,所以上述的代码是有误的。我们应该在引用 b 前加上 const 。

  引用做返回值同样也会有效率问题。以返回值类型为值,在返回期间,函数不会直接者将变量本身直接返回,而是返回变量的一份临时的拷贝,因此用值返回值类型,效率是非常低下的,尤其是返回值类型非常大时,效率就更低。

  通过下面的对比也可看出:

#include <time.h>
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A& TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
 // 以值作为函数的返回值类型
 size_t begin1 = clock();
 for (size_t i = 0; i < 100000; ++i)
 TestFunc1();
 size_t end1 = clock();
 // 以引用作为函数的返回值类型
 size_t begin2 = clock();
 for (size_t i = 0; i < 100000; ++i)
 TestFunc2();
 size_t end2 = clock();
 // 计算两个函数运算完成之后的时间
 cout << "TestFunc1 time:" << end1 - begin1 << endl;
 cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

  运行结果如下:

 2、4 引用总结

  在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
  我们通过如下代码对比可知:
int main()
{
 int a = 10;
 
 int& ra = a;
 ra = 20;
 
 int* pa = &a;
 *pa = 20;
 return 0
}

  我们看其汇编代码:

  其次我们对比一下指针和引用的区别:

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

三、内联函数

3、1 内联函数的引出

  我们知道函数的调用是有所消耗的,需要开辟栈帧。为了提高效率呢,我们有时候可以选择用宏函数来替代函数调用。例如下面代码就可以用宏函数替代:

//int add(int x, int y)
//{
//	return (x + y) * 10;
//}

#define ADD(x,y) (((x)+(y))*10)
int main()
{
	//int ret = add(1, 2);

	//宏函数
	int ret = ADD(1, 2);

	cout << ret << endl;
	return 0;
}

  注意,在使用宏函数时,一定不要吝啬括号。如果少一些必要的括号的话,会出现预想不到的错误。因为宏是在编译时进行完全的替换。

  但是宏能替换所有的函数吗?答案是不可能的。稍微复杂的函数,用宏来替换就十分复杂。我们再来看一下宏的优缺点,先看优点:

  • 增强代码的复用性;
  • 提高性能;
  我们再来看一下宏的缺点:
  • 不方便调试宏。(因为预编译阶段进行了替换);
  • 导致代码可读性差,可维护性差,容易误用;
  • 没有类型安全的检查 。
  宏的替换并不是很好,且在大多情况下用宏来替换的复杂度很高、可读性差。那还有什么方法呢?C++中引出了内联函数,我们接着往下看。

3、2 内联函数详解

3、2、1 内联函数的概念

  以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

3、2、2 内联函数的特性

  内联函数有以下特性:

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现),不是递归、频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。下图为《C++prime》第五版关于inline的建议:
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地
    址了,链接就会找不到。
    // F.h
    #include <iostream>
    using namespace std;
    inline void f(int i);
    // F.cpp
    #include "F.h"
    void f(int i)
    {
    	cout << i << endl;
    }
    // main.cpp
    #include "F.h"
    int main()
    {
    	f(10);
    	return 0;
    }
    // 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl f(int)" (?
    //f@@YAXH@Z),该符号在函数 _main 中被引用

四、auto关键字(C++11)

4、1 auto简介

  在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它,大家可思考下为什么?
  C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
  我们看auto的使用方法,如下:
#include<iostream>

using namespace std;

int TestAuto()
{
	return 10;
}

int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = TestAuto();

	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;

	//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
	return 0;
}

   运行结果如下:

  从这个用例中,我们可大致了解auto的用法及其作用,但是自动推出类型的意义大吗?上述并不能很好的体现出来,我们看下面的一个例子。 

#include <string>
#include <map>
int main()
{
	std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange", "橙子" },
	{"pear","梨"} };
	std::map<std::string, std::string>::iterator it = m.begin();
	while (it != m.end())
	{
		//....
	}
	return 0;
}

   通过上面的代码,我们可以看出来随着程序越来越复杂,程序中用到的类型也越来越复杂。含义不明确又很容易导致出错。我们第一反应是可以通过typedef给类型取别名,比如:

#include <string>
#include <map>
typedef std::map<std::string, std::string> Map;
int main()
{
	Map m{ { "apple", "苹果" },{ "orange", "橙子" }, {"pear","梨"} };
	Map::iterator it = m.begin();
	while (it != m.end())
	{
		//....
	}
	return 0;
}

   但是auto从不能解决所有的情况。在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的类型。然而有时候要做到这点并非那么容易,因此C++11就引出了auto。

  注意:使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

4、2 auto的使用细节

4、2、1 auto与指针和引用结合起来使用

  用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。具体我们可看下面代码: 

int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;  //引用
	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	*a = 20;
	*b = 30;
	c = 40;
	return 0;
}

   运行结果如下:

4、2、2 在同一行定义多个变量

  当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。我们可结合下面代码一起理解一下:
void TestAuto()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

4、3 auto不能推导的场景

  以下几点都是auto不能推到的场景:

  • auto不能作为函数的参数;
    // 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
    void TestAuto(auto a)
    {}
  • auto不能直接用来声明数组;
    void TestAuto()
    {
       int a[] = {1,2,3};
       auto b[] = {4,5,6};  //错误
    }
  • 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法;
  • auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439997.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谷歌浏览器的跨域设置、配置、新老版本Chrome

文章目录 1、个人开发中的使用习惯2、老版本Chrome浏览器(版本号49之前)3、新版本Chrome浏览器(版本号49之后) 1、个人开发中的使用习惯 下载好谷歌浏览器以后&#xff0c;快捷方式一份放在桌面上&#xff0c;一份放在开始菜单栏&#xff0c;桌面的重命名为dev(可以随意命名)&a…

【09 cookie and session】

cookie and session 一、cookie1. 会话技术2. 什么是cookie3. cookie的属性4. cookie方法5. cookie添加和获取6. 需求案例7. cookie的细节 二、session1. HttpSession介绍2. HttpSession常用方法3. HttpSession获取4. HttpSession使用5. HttpSession使用细节 一、cookie cooki…

【MongoDB】什么是MongoDB?MongoDB有什么特点?MongoDB的适用场景?

什么是MongoDB数据库&#xff1f; MongoDB是一个开源、高性能、支持海里数据存储的文档型数据库。 MongoDB是一个高效的非关系型数据库&#xff08;不支持表关系&#xff1a;只能操作单表&#xff09; MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系…

postman安装

目录 下载、安装 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。 Postman原是Chrome浏览器的插件&#xff0c;可以模拟浏览器向后端服务器发起任何形式(如:get、post)的HTTP请求 使用Postman还可以在发起请求时&#xff0c;携带一些请求参数、请求头等信息…

debezium docker订阅oracle 11g

debezium 依赖于kafka&#xff0c;kafka依赖于zookeeper。 zookeeper实现了kafka消息的一致性&#xff0c;debezium 把订阅的数据推送到kafka dockerFile FROM debezium/connect:1.6 ENV KAFKA_CONNECT_JDBC_DIR$KAFKA_CONNECT_PLUGINS_DIR/kafka-connect-jdbc ENV INSTANT_C…

登陆拼多多获取整站实时商品详情数据,商品列表,商品优惠券,包括数据采集,清洗,分析,封装等过程,作为爬虫的课程。

前言 拼多多平台是一个众所周知的一个电商平台&#xff0c;基本上什么都能找到&#xff0c;而且价格比较优惠。 想业余做电商赚点小钱或买点东西&#xff0c;就需要对比平台上各个卖家的商品信息&#xff0c;所谓货比三家&#xff0c;为商品定一个合理的价位或淘一个合理&…

[Python基础] 学生管理系统(存储读取学生信息)

学生管理系统&#xff1a;应该算是语言语法学习过程中一个比较适合测试语法熟练度的代码案例了。 文章目录 思路main&#xff08;入口函数&#xff09;menu&#xff08;菜单&#xff09;Add&#xff08;新增学生&#xff09;Display()&#xff08;显示学生&#xff09;Find()&a…

::before和::after伪元素的用法案例

CSS3中伪类采用单冒号写法&#xff0c;伪元素采用双冒号写法。 伪类举例——:hover,:link,:active,:target。 伪元素举例——::before,::after,::first-letter,::first-line,::selection。 一、介绍 今天写网页时遇到一个问题&#xff0c;视口的背景中插入一个小图标的话&a…

Python进阶项目--只因博客(bootstrap+flask+mysql)

前言 1.全民制作人们大家好&#xff0c;我是练习时长两年半的个人练习生只因坤坤&#xff0c;喜欢唱&#xff0c;跳&#xff0c;rap&#xff0c;篮球&#xff0c;music......在今后的节目中&#xff0c;我还准备了很多我自己作词、作曲、编舞的原创作品&#xff0c;期待的话&am…

VirtualBox虚拟机后台运行

前言 在Windows下的VirtualBox运行如Linux的虚拟机时&#xff0c;并不需要图形化的界面&#xff0c;我们不必次次通过VirtualBox的官方界面进入&#xff0c;解决鼠标键盘定位等问题。可以通过Putty等软件使用SSH进行连接控制&#xff0c;但是官方界面并没有在后台运行选项。 需…

Nginx快速上手~

注&#xff1a;本文针对官网的快速入门教程进行一个中文的解释&#xff0c;以帮助英文阅读能力较差的学习者快速上手 参考官网连接Beginners Guide (nginx.org) Centos下的安装 sudo yum install yum-utils # 创建文件 vim /etc/yum.repos.d/nginx.repo # 输入以下内容 ####…

项目1实现登录功能方案设计第四版

需求 优化点:MySQL表常用功能模块实现方案 index页面home页面 需求 实现一个登录功能 实现的功能 注册(邮箱注册) 登录(邮箱密码) 重置密码 查看操作记录(登录, 注册, 重置密码, 登出. 都算操作) 登出 在第3版的基础上进行优化:\ 优化点: 接口设计 1. 发送注册验证码: 路径: PO…

五一将迎2亿人次出行,君子签助力旅行社合规高效签旅游电子合同

近日&#xff0c;为规范旅游市场秩序&#xff0c;促进旅行社高质量发展&#xff0c;文旅部发布了《文化和旅游部办公厅关于进一步规范旅游市场秩序的通知》&#xff08;下称《通知》&#xff09;&#xff0c;对旅游业提出了新的要求。 《通知》中规范了旅行社经营行为。旅行社要…

flink任务处理下线流水数据,数据遗漏不全(三)

flink任务处理下线流水数据&#xff0c;数据遗漏不全&#xff08;二&#xff09; 居然还是重量&#xff0c;做一个判断&#xff0c;如果是NaN 就直接获取原始的数据的重量 测试后面会不会出现这个情况&#xff01; 发现chunjun的代码运行不到5h以后&#xff0c;如果网络不稳…

EasyCVR平台基于GB28181协议的语音对讲配置操作

EasyCVR基于云边端协同&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台可支持海量视频的轻量化接入与汇聚管理&#xff0c;可提供视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联等功能…

IT行业里的热门技术

© Ptw-cwl 文章目录 1. 人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;2. 大数据3. Web2.04. 移动应用程序开发5. 物联网6. 云计算7. 区块链8. 5G技术9. 虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09; 现在如果问…

如何使用Midjourney辅助建筑设计,常用的提示和使用效果展示(内附Midjourney提示词网站)

文章目录 一.Midjourney建筑设计的提示技巧1. prompt模板12.prompt模板2 二、著名建筑师为例1.Zaha Hadid&#xff08;扎哈哈迪德&#xff09;2.Ludwig Mies van der Rohe&#xff08;路德维希密斯凡德罗&#xff09;3.Renzo Piano&#xff08;皮亚诺&#xff09;4.Stefano Boe…

PEIS源码,体检管理系统源码,C#医院体检系统源码

PEIS体检管理系统源码&#xff0c;医院体检系统源码PEIS源码&#xff0c;商业级源码&#xff0c;有演示。 PEIS医院体检管理系统采用C/S结构&#xff0c;前台开发工具为Vs2012&#xff0c;后台数据库采用oracle大型数据库。核心功能有&#xff1a;体检档案的录入、体检报告的输…

从入门到精通:SEO站外优化全面解析

通过​​第三章​​上下连续两期的干货内容&#xff0c;相信你已经掌握了 SEO 优化的基本方法&#xff0c;但你有没有发现&#xff1a;之前的内容都是针对网站本身进行优化的方法&#xff0c;其实&#xff0c;SEO 还有相当一部分功夫要放在站外优化上。 问题来了&#xff1a;站…

上海震坤行工业超市聚焦量具量仪市场,助力企业实现测量数字化

上海震坤行工业超市聚焦量具量仪市场&#xff0c;助力企业实现测量数字化 近日&#xff0c;量具量仪三大品牌哈量、广陆、英示的三位重磅嘉宾及震坤行磨具量具产线总经理&#xff0c;走进震坤行工业超市直播间。带来了一场“聚焦量具量仪市场&#xff0c;助力企业实现测量数字…