C++感受9-Hello Object 生死版•上

你好对象!

  1. 认识C++中基础中的基础类型;
  2. 创建用户自定义的复合类型;
  3. 创建新类型的对象;
  4. 定制新类型对象的生死过程

零、面向对象启蒙

之前我们一直在问候世界,从这节课开始,我们的问候对象就是“对象(Object)”了。
今天是这个系列的第一节:《Hello Object 生死版.上》。

今天这节课,我们要学习如何创建物种以及如何创造对象,展开讲,包括:

  1. 在C++代码中创建一个新物种;
  2. 为这个新物种创造一个对象;
  3. 定制新创建的物种对象出生与对象死亡的过程。

这里提到了两个关键概念:物种和对象,大家能理解二者的区别吗?

“物种”就是一种生物的类型,而“对象”,是属于这种生物类型的,一只活生生的实体。比如,作为物种,恐龙(物种)是存在的,但是,今天的这个世界里,已经不存在,具体的某一只恐龙(对象)了。

之所以要把“对象”设定为后面许多课的重要学习对象,是因为有一种重要的编程思想叫作“面向对象编程”;英文是 Object Oriented Programming,简称OOP——面向对象编程。

直译的话就是“以对象为导向的方法来编程”,也可以理解为:围绕对象来设计、组织你的代码结构。

新知识通常需要以旧知识作为基础。之前我们已经写过至少6个版本的“问候”程序。比如:函数版、交互版、分支版、循环版等等。当时我们所使用的,是什么编程思想呢?有没有一种可能,我们一直都在写“没有思想”的代码呢?

当然不是。之前我们一直在使用“面向过程” (Procedure Oriented Programming)的思想在编写代码。

面向过程是一种特别自然而然的思想,因为在生活中我们就是这样处理事情的:

面向过程思想:把做一件大事情拆解为做几件比较小的过程。如有必要,再把一个小的过程拆成更小更小的过程。

面向过程就是一种典型的“大事化小,小事化了”的思路体现。

把“过程”对应到“函数”,大家是不是马上就能够认同:之前我们写的问候程序采用的是“面向过程”的方法。在 Hello World 例程的第一个版本,也就是第五节,《逐字逐句深入理解C++最小例程》,我们就讲过:

“把程序理解成是在做一件大事,那么,这件大事对应的就是main主函数”

而后的课程,在需求的不断增加与实现版本的不断演化的过程中,我们慢慢的把 “上班路上问候同事”这件事情(对应 main() 主函数)拆成两个小过程(函数):

  • Input() 函数:用来模拟实现遇到同事;
  • Hello() 函数:用来模拟实现问候同事。

“大事化小,小事化了”,“面向过程”的编程思路确实是非常地自然而然,但是,如果一件复杂的事情大到一定程度的时候,就会出现事情仿佛千头万绪,我们甚至不知道如何开始的情况。

举个例子:假设2030年,国家又要承办一场奥运会,而你突然被全国人民推到该届奥运总负责人的岗位,此时,你觉得自己应该如何开始?

正确的方法应该是:找人,找人才,找各项事情的总负责人。开幕式、场地、安全保障,经济收入、来宾接待,传播以及赛事自身,等一大堆事,你不可能样样擅长——你甚至一样都不擅长,因此你必须为每类事情,都找一个总负责人。

为不同类型的事情,找一个具备处理此类事情的方法的负责人。这里面有四个关键字:类型、事情、方法、负责人。其中“事情”还是对应到“函数”,而类型、方法、负责人对应C++代码中的什么呢?
答案如下:

现实世界代码世界备注
事情普通函数已学
类型数据类型,特别是用户自定义复合类型-
方法和类型紧绑定的函数:成员函数也经常就被称为:方法

小结一下: 当问题慢慢变复杂,作为解决者,我们所考虑的,将慢慢地从具体某一件事情要如何解决,转成为某一类事件,找一个具备处理方法人才;这就是面向过程到面向对象的转换的最初原因。

一、网课开始

ff12-HelloObject-生死版-上

二、类型即约束!

面向对象的编程无法一蹴而就,今天我们只需建立对“对象”的一种感性认识即可。那么,什么叫对象? 老办法,让我们还是从问题、从需求开始说起。之前我们写的问候程序,一直在使用一个人的名字叫什么来判断这个人是不是我们心目中的女神,如:

if (XXX == "志玲") { cout << "亲爱的女神!" << endl; }

这种判断方法存在重大的逻辑漏洞。天底下叫“志玲”的人多去了,但并不是叫“志玲”的人都是我闪心目中的女神。

一个数据的名字,对这个数据会有什么内容是无法保证的,即:数据的名字,对数据的内容,以及数据的外在表现,都不会有实质的约束力。

那么,什么可以约束一个数据的内容呢?
答:数据的类型!

比如,作为数据,作为对象,我们都是人,我们的类型就是“人类”,而“人类”这个类型,对人的约束,就是“要做人事”。如果有人不做人事,我们就会鄙视并痛哭他:“你真不是个人!”,这是一种伤人很深的骂法,因为,它从类型上否定了一个,相当于从根源上否定了一个人。

类似的,如果有人女生偶尔骂你 “你真是头猪”,相信你并不会太在意,因为对方通常只是在嫌你在某些事情上笨了一些。如果这个女人骂的是 “你真不是个人……”你觉得怎样?

有没有比 “你真不是个人” 更狠的呢?当然有,一会儿我们就会给出答案。

三、C++常见内置基础类型

类型是这么的重要,所以编程语言都会内置一些常用的基础类型,我们先来快速学习C++的五种基础中的基础类型,重点观察不同类型对各自数据的约束是什么?

3.1 整数类型 / int

int 是 integer的缩写。

既然是整数,肯定得能参于加(+)减(-)乘(*)除(/)等数学计算的;其中有细则,比如 0 不允许当除数。

就像网上常有的口号 “不怎样怎样,你就不是什么什么”一样,如果有个数,它无法参加加法计算,我们就可以“指责”它:“你丫的肯定不是个整数!”。

整数不带有小数的信息,因此,如果两个整数做除法,比发 7 / 2 ,将得到另一个整数:3,而不是 3.5。

int a = 7 / 2; // 得3,而非3.5

3.2 字符类型 / char

char 是 character 的缩写。

这里有一句话:“远上寒山石径斜”,请问它包含几个字?答7个。
字符就是一句话,一段文本中的一个字,或者一个标点符号,也包括空格、换行、缩进符等等。
可惜,在C/C++被发明的时候,计算机并未足够全球普及,因此,汉字并未被C/C++语言视为一个字符。因此,上面例子,只能改为:

这里有一句话:“How are you?”,请问它包含几个字符?答:12个。

计算机中,一切数据本质都是数,char 也能被无损地转成 int 类型,依情况被转换至 -128 ~ 127或者 0 ~ 255 之间的某个整数。

C/C++字符类型对数据,也就是字符的约束还有:一个字符数据只能存储在一个字节(byte)的内存里。字节是计算机程序可以单独处理的最小内存单位。有多小呢?最常见的情况,正如上一段所说的结果:小到只能存放 256 种数据——而这也正是C/C++中的字符无法存储汉字的原因,中文何止 256 个汉字!

在C/C++代码中,字符的字面表达,需要使用单引号包含,如:

char a = 'A';
char b = 'b';
char c = ',';

3.3 布尔类型 / bool

bool 是 boolean 的缩写。

现实中或许并没有非黑即白的事,但是有些事情,真就是真,假就是假。表达这种非真即假,非假即真的数据,就需要用 布尔(boolean)类型。

比如,女朋友问你:“爱我吗?”,你的答案也许可以使用 int 类型,回答她:“我爱你100”——但是,我们的专业建议是,请使用 bool 类型。

C++中,用关键字 true 表示真,false 表示假。二者都可以无损转换为 int 类型。其中 false 将被转换为 0,而 true 将被转换为 1,因此,尽管没什么意义,但是计算:

int v = false + true; 

这样代码是合法的,v 将得到 1 。

反过来,如果将 int 转换成 bool 类型数据,就是有损的了。其中 0 被转为 false,所有非 0 都被转为 true (很多信息,被弱化成一个信息,这就叫有损转换)。

bool b1 = true; bool b2 = 999; int v = b1 + b2; // v 是多少? 

上例中,v 将得到 2。

3.4 浮点类型 / float / double

带小数信息的数据,比如 3.14、2.5、99.999、100.0,在计算机中通常使用一种叫“浮点”,也就是 “float point” 的格式存储、表达。注意,当你刻意地写 “100.0”时,它就不是一个整数,而是一个正好小数位是0的浮点数。

和生活中一样,在计算机,表达、存储、计算带小数的数,代价都远大于整数(所以小学生都是先学整数的四则运算,后面才学的小数、分数)。为了避免浪费,C++将浮点数,又按能表达的精度范围的大小,分成两种:单精度浮点数和双精度浮点数,即 float 和 double。具体的精度可以将来再了解,现在只需要建立感性认识,请看例子:

float f = 3.14159265358; double d = 3.14159265358; 

例中,如果你再将 f 输出,会发现仅前面的 3.141592 是正确的,其后的小数位,可能都是错的。而 d 就没有这个问题。

3.5 标准库基础类型

除了语言内置的简单类型以外,C++标准库还提供了不少常用的基础类型,注意,它们都不是语言内置的,而且也并不算“简单”。它们被称为“标准库基础类型”,有别于前述的“内置基础类型”。

我们已经简单学习及多次使用过的标准库基础类型,这它俩:

  • std::string(标准库字符串类型)
  • std::string_view(字符串视图类型、即喜欢偷看的 “字符串观察者”)

(更多C++基础类型学习,记得到 d2school.com 站)

四、用户自定义复合类型

世间的事物这么丰富、复杂,如果我们只有语言的内置类型,什么 int、char、bool、float、double……哪怕再加上标准库提供的基础类型,也是无法表达的。比如,人,应该用什么类型表达?

之前,我们就一直使用 std::string (字符串)来表达人的姓名,这自然很好,因为姓名本来就是字符串。不好的地方,或者存在严重逻辑错误的是:我们用姓名代表一个人,并且,还用姓名叫什么,来判断一个人是不是我们心目中的女神……错大发了!

为了解决这个问题,计算机编程语言支持我们通过组织简单类型,来形成复杂类型,全称是“用户自定义复合类型”。这里的“用户”就是指程序员,也就是我们。而“复合”,则是在表明:新类型是由多个类型组合起来的。

组合过程是可递进的。比如,假设将 int、float、bool 三者组成一个新类型,称为 T1, 那么,可以将 T1 和 char、std::string 再组成又一个新类型。

int、float、bool 的组合,大家能想象一些实际用途吗?

我想了两个:

  • int : 表达年龄;
  • float:表达每月收入,且因收入不高,又仅精确到分,故float精度够用,无需double;
  • bool :是否低保户;

显然,贫穷限制了南老师的想象力,再来一个——

  • int : 表示本学期的第几次英语单元考;
  • float: 表示得分(小数部分只需有 0.0 / 0.5 );
  • bool: 是否低于本次考试全班平均分;

显然,这次限制南老师想象力的,应该是长期低学分的学渣身份。

五、实战定义新复合类型

前面举的例子,于本课的学习目标来说,都过于具体、过于细节了,无法体现本课学习的高度。我们的高度是:当代码世界中的上帝,随心所欲地创建类型。

尽管在史上真的存在过恐猪(daeodon)和恐蛇(dinilysia)物种,但是,我们将无视这一事实,自行创建我们心目中的“恐猪”和“恐蛇”类型,对应的英文名字也不一样,分别是:DinosaurPig 和 DinosaurSnake。

5.1 定义新结构类型

以 DinosaurPig 类型为例,定义一个新的复合类型的最简语法是:

struct DinosaurPig { }; 
  • 关键字 “struct” 来自 “structure 结构”,很好理解:通过组合一些成员,从而到一种新的结构类型嘛,小时候玩过积木的同学,肯定理解。

  • “struct” 之后(有至少一个空格)就是新类型的名字,此例为 DinosaurPig;

  • 名字之后需要一对花括号,这和我们之前写函数体很像,关键区别见下一点;

  • 在定义新类型最后,即 ‘}’ 之后,需要有一个分号;

请同学们自己写出恐蛇的定义。

就这样吗?这就是 “恐猪” 的结构??我们只定义了新的复合类型的名字,却没有为这种复合类型定义任何内部组成的类型及数据。比如,恐猪有没有长角?有没有獠牙?有没有翅膀?我们统统不管了,别问为什么,问就是想象力很贫乏。

结构名字之后的那对花括号内部,确实就是用来定义新类型应该有哪些类型的组成部分的——但如前所述,这些知识点对本课而言,过于具体、过于细节了,高度不够。

尽管有名无实,但我们确实定义了一种新类型,只是没有在这个类型里提出它对本类数据的约束。不过,有一种类型,它就真的无需对数据进行约束。

请思考:如果我们要为世间的万物,定一个类型,那么:

  • 第一、这个类型应该叫什么名字?
  • 第二、这个类型又该由哪些类型组合而成?

更具体一点,请你叫来一个小学生,然后问他:风、国画、牛、石油、棒棒糖的共同分类是什么?

小学生肯定要冲你翻白眼。

冲你翻白眼的小学生肯定没有学过面向对象编程,并且多半没有读过《般若波罗蜜多心经》中的“色即空、空即色”,或者《道德经》中的 “无名天地之始,有名万物之母”。

用中文表达的话,世间万事万物的共同类型,就应该叫 “事物类型”,或者 “东西类型”。因为一切都是东西。比如正在阅读本文的你,请问,为师我可以说你“不是个东西”吗?

男人女人都是人类,而狗、蛇、虫子、人都是动物类型,而 花、草、动物都是生物类型;而石油、花、人、狗、风、国画、牛、棒棒糖,它们都是“东西”。

比 “你真不是个人” 更狠的骂法也有答案了:“东西”类型远比“人类”更加根源,所以,骂“你真不是个东西”的杀伤力要远大骂“你真不是个人”。

用英文的话,世间万事万物的共同类型就是“Object”,Object即有事物、东西、对象的含义,为了让C++程序听起来高雅一些,中文世界的计算机前辈们选择了“对象”这个翻译。

原来如此,所谓的面向对象编程,原来就是面向东西编程而已……

别胡思乱想了,集中精力,来看超超超级重要的代码:东西类,也就是对象类型,应该如何定义:

struct Object
{
   /* 一片虚空 */
};

在某些语言里,你可能当不了“上帝”,因为那些语言会直接内置 Object 类型,你将因此而丧失实现自行定义世间万物最根源的类型的权利。

花括号中仍然只需保持一片空白即可。我们加了一句注释,是因为此刻它虚空得理直气壮:为对象类型添加任何组成成员,就是对世间的所有东西添加了某种约束——而一旦你添加了任何约束,就必然会造成世间万物中,可能会有某一种东西,正好不满足这个约束,于是这种东西就再属于“东西”……

如果你还不懂得“约束”的话,很可能是因为你还年轻,还没接受过社会的毒打,让我们改为定义爱情是什么吧……

struct Love 
{ 
   /* 爱情需要由什么组成呢? */ 
}; 

把这个定义交给你的女朋友,相信她会抱怨:纸不够长,写不完我对爱情的定义:180平的房,1米8的身高,180万的存款……

定义类型,就是在定义约束;因为:类型即约束。

有了类型,接下来我们可以为类型创造出对象。和平常定义变量并没有区别。事实上,对象也是变量(或常量),只是,基础类型的数据习惯称为变量,而复合类型的变量习惯称为对象

请完成以下例程:

struct Object
{ 
};

struct DinosaurPig
{
};

struct DinosaurSnake 
{
};

int main()
{
    Object o;
    DinosaurPig pig;
    DinosaurSnake snake;
}

六、实战构造与析构

上面的程序运行后,屏幕输出也将“一片虚空”,尽管身为“上帝”,我们心里清楚曾经有一个东西、一头猪、一条蛇来到过主函数的世界,只是它们悄悄地来,又悄悄地走了……

要怎么才能实现肉眼可观察的,对象的生和死呢?

前面我们说过,采用面向对象的思想编程时,我们就是在为特定类型的事找特定的“人才”,那么,定义一个新的复合类型的目的,本质就是要培养出某一种“类型”的“人才”。

这就要引入“成员函数(member function)”的概念。

为了让特定类型的“人才”具备特定的功能,我们仍然需要写函数——毕竟函数代表做事情——只是,此时我们所写的函数紧密地绑定到某一种类型身上,这种函数在C++中称为类型的成员函数。在更多的面向对象语言里,通常称为“方法/method”,即类型的方法。

让我们还是费点脑细胞,为前面的 “恐猪” 类型,想象一个“方法”吧,比如说 “拱”,那么,“DinosaurPig” 就可以拥有一个方法(成员函数)叫做 “RootAround()”。注意,这个“拱”是特属于恐猪的,和家猪的“拱”是各自的拱法。

C++是个有趣的语言,除了可以给特定类型(的对象)做某事的特定的方法以外,它还允许我们为特定类型(的对象)定制生或死的过程。

定制类型的生的过程,是一种特殊的方法(成员函数),叫构造函数(Constructor),定制类型的死的过程,则是析构函数(Destructor)。

成员函数和普通函数在定义语法上,存在不同。因为成员函数和特定类型紧密相关,所以它可以直接写在类型的内部,即复合类型的那一对花括号内。

构造函数和析构函数又是特殊的成员函数,它们都不能带函数的返回值类型声明,注意,不是指函数返回 void ,而是就不能写返回值类型。

构造函数和析构函数都不能写返回值类型,这显然是一种规定。可以按如下方法,理解这个规定(尽管并不100%正确):

  • 构造函数:负责对象生的过程,其返回结果自然是类的一个新对象,因此无需写返回类型;
  • 析构函数:负责对象死的过程,过程执行后,对象就死了,还有必要有返回值吗?

语义与逻辑上看,Object 类型显然还是应该保持一片虚空才对,只是为了观察它的对象的出生与死亡过程,所以我们才为它添加了构造与析构,且二者都是往屏幕上输出点肉眼可看到的内容。

构造函数和析构函数在命名上也有特殊要求,前者必须和类型名一致,比如 Object(),后者则为类型名字前面加一波浪线,比如:~Object();

#include <iostream>

struct Object
{
    Object()
    {
        std::cout << "Hello world!" << std::endl; //来自对象的,对世界的问候
    }

   ~Object()
   {
        std::cout << "Bye-bye world!" << std::endl; // 对象对世界的告别
   }
}; // <--- 千万别忘记分号

“恐猪”和“恐蛇”在本课只是在陪太子读书,大家自行发挥它们的生死过程的定制吧。

完成这个程序,你的一只脚已经悄然,迈过了面向对象世界大门的门槛了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

验证 python解释器是否安装成功

一. 简介 前一篇文章学习了下载并安装 python解释器&#xff0c;文章如下&#xff1a; windows系统下python解释器安装-CSDN博客 本文验证 python解释器是否安装成功。 二. 验证 python解释器是否安装成功 1. 首先&#xff0c;打开 Windows系统的 "cmd" 界面。…

Netty学习——实战篇8 Handler链调用、TCP粘包和拆包

1 Handler链调用-需求 使用自定义的编码器和解码器来说明Netty的Handler调用机制。客户端发送long类型数据到服务端&#xff1b;服务端发送long到客户端。 2 Handler链调用-实战 2.1 NettyServer.java public class NettyServer {public static void main(String[] args) {…

C语言——小知识和小细节16

一、左旋字符串 例如字符串 abcd &#xff0c;左旋一个就是 bcda &#xff0c;左旋两个就是 cdab 。 方法一&#xff1a;循环 #include <stdio.h> #include <string.h>void func(char* str, int n) {int i 0;int j 0;int len (int)strlen(str);n % len;//超出…

算法打卡day48|动态规划篇16| Leetcode 583. 两个字符串的删除操作、72. 编辑距离

算法题 Leetcode 583. 两个字符串的删除操作 题目链接:583. 两个字符串的删除操作 大佬视频讲解&#xff1a;583. 两个字符串的删除操作视频讲解 个人思路 本题和115.不同的子序列相比&#xff0c;变为了两个字符串都可以删除&#xff0c;整体思路是不变的&#xff0c;依旧…

vue 表格获取当前行索引,加颜色

vue 表格获取当前行索引&#xff0c;加颜色 <span styledisplay:inline-block;width:10px;height:10px;border-radius:50% :style"{background:color[scope.$index]}" />//定义颜色color: [#5387F7, #A794E0, #F3543C, #999999, #77D3F8, #FFA1B4, #26CEBA, #…

ElementUI RUOYI 深色适配

1. 切换按钮&#xff1a;随便找个页面放上去 页面触发逻辑如下 a. html 按钮结构&#xff08;可自定义&#xff09; <el-switchstyle"margin-top: 4px; margin-left: 8px; margin-right: 8px"v-model"isDark"inline-promptactive-icon"Moon"…

使用 Gradio 的“热重载”模式快速开发 AI 应用

在这篇文章中&#xff0c;我将展示如何利用 Gradio 的热重载模式快速构建一个功能齐全的 AI 应用。但在进入正题之前&#xff0c;让我们先了解一下什么是重载模式以及 Gradio 为什么要采用自定义的自动重载逻辑。如果你已熟悉 Gradio 并急于开始构建&#xff0c;请直接跳转到第…

vite和webpacke的常规配置

文章目录 1、vite和webpacke的区分2、vite的常规配置介绍主要部分介绍vite基本配置示例 3、webpacke的常规配置介绍主要部分介绍Webpack 基本配置示例 1、vite和webpacke的区分 相同点&#xff1a; 都是构建工具&#xff0c;用于资源打包 &#xff1b; 都有应用到摇树原理 tre…

网络研讨会 | 数据中心中的人工智能

人工智能&#xff08;AI&#xff09;是嵌入式开发人员必须解决的最复杂的技术之一。将其集成到您的系统中会带来很多问题而不是很多答案。行业媒体Embedded Computing Design特地推出“工程师的人工智能集成指南”月度网络研讨会系列&#xff0c;目的是尽可能地简化嵌入式计算设…

「共沐书香 分享喜“阅”」世界读书日交流活动在国际数字影像产业园圆满举行

人间最美四月天&#xff0c;正是读书好时节。4月23日&#xff0c;在数媒大厦的春日里&#xff0c;我们共同迎来了第29个“世界读书日"。由数字影像联合工会委员会、树莓科技&#xff08;成都&#xff09;集团有限公司工会委员会主办&#xff0c;成都树莓信息技术有限公司、…

Linux(韦东山)

linux和windows的差别 推荐学习路线 先学习 应用程序 然后&#xff1a; 驱动程序基础 最后&#xff1a;项目 韦东山课程学习顺序 看完第六篇之后&#xff0c;还可以继续做更多的官网的项目 入门之后&#xff0c;根据自己的需要学习bootloader / 驱动大全 / LVGL

误差的一阶和二阶——MSE/MAE

variance和bias MSE之前&#xff0c;先看两个更为朴素的指标&#xff1a;variance和bias。 在打靶中&#xff0c;有的人所有的子弹都离靶心很远&#xff0c;偏差显然过高&#xff0c;但是很稳定地维持在某一点附近&#xff1b;有的人平均环数更高&#xff0c;但是分布太过分散…

网络安全之SQL注入漏洞复现(中篇)(技术进阶)

目录 一&#xff0c;报错注入 二&#xff0c;布尔盲注 三&#xff0c;sleep延时盲注 四&#xff0c;DNSlogs 盲注 五&#xff0c;二次注入 六&#xff0c;堆叠注入 总结 一&#xff0c;报错注入 报错注入就是在错误信息中执行 sql 语句&#xff0c;利用网站的报错信息来带…

2024-04-23 linux 查看内存占用情况的命令free -h和cat /proc/meminfo

一、要查看 Linux 系统中的内存占用大小&#xff0c;可以使用 free 命令或者 top 命令。下面是这两个命令的简要说明&#xff1a; 使用 free 命令&#xff1a; free -h这将显示系统当前的内存使用情况&#xff0c;包括总内存、已用内存、空闲内存以及缓冲区和缓存的使用情况。…

使用 Flutter 打造引人入胜的休闲游戏体验

作者 / Zoey Fan 去年&#xff0c;Flutter 休闲游戏工具包进行了一次重大更新。近期在旧金山举办的游戏开发者大会 (GDC) 上&#xff0c;Flutter 首次亮相。GDC 是游戏行业的顶级专业盛会&#xff0c;致力于帮助游戏开发者不断提升开发技能。欢迎您继续阅读&#xff0c;了解开发…

小程序AI智能名片商城系统如何依赖CPM、CPC、CPS技术应用进行营销

在数字化营销的新纪元中&#xff0c;小程序AI智能名片商城系统以其高效、智能的特性&#xff0c;成为了企业营销的重要工具。而CPM、CPC、CPS这三种技术应用&#xff0c;更是为该系统赋予了强大的营销能力。接下来&#xff0c;我们将通过详细的例子&#xff0c;探讨这些技术是如…

微信小程序webview和小程序通讯

1.背景介绍 1.1需要在小程序嵌入vr页面&#xff0c;同时在vr页面添加操作按钮与小程序进行通信交互 1.2 开发工具&#xff1a;uniapp开发小程序 1.3原型图 功能&#xff1a;.点击体验官带看跳转小程序的体验官带看页面 功能&#xff1a;点击立即咨询唤起小程序弹窗打电话 2.…

力扣数据库题库学习(4.23日)

610. 判断三角形 问题链接 解题思路 题目要求&#xff1a;对每三个线段报告它们是否可以形成一个三角形。以 任意顺序 返回结果表。 对于三个线段能否组成三角形的判定&#xff1a;任意两边之和大于第三边&#xff0c;对于这个表内的记录&#xff0c;要求就是&#xff08;x…

【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)

男儿不展风云志&#xff0c;空负天生八尺躯。——《警世通言卷四十》&#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;C笔记专栏&#xff1a; C笔记 &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 上篇…

vue项目启动npm install和npm run serve时出现错误Failed to resolve loader:node-sass

1.常见问题 问题1&#xff1a;当执行npm run serve时&#xff0c;出现Failed to resolve loader: node-sass&#xff0c;You may need to install it 解决方法&#xff1a; npm install node-sass4.14.1问题2&#xff1a;当执行npm run serve时&#xff0c;出现以下错误 Fa…