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

Linux环境C语言开发基础

C语言是一门面向过程的计算机编程语言,与C++、C#、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
C语言诞生于美国的贝尔实验室,由丹尼斯·里奇(Dennis MacAlistair Ritchie)以肯尼斯·蓝·汤普森(Kenneth Lane Thompson)设计的B语言为基础发展而来。在它的主体设计完成后,汤普森和里奇用它完全重写了UNIX,且随着UNIX的发展,c语言也得到了不断的完善。1989年,诞生了第一个完备的C标准,简称“C89”,也就是早期的“ANSI C”,截至2023年,最新的ISO的C语言标准为"C2x"。👴
作为嵌入式工程师,跟C语言打交道是不可避免的。本篇文章抛弃了根据C语言语法点逐个分析讲解的做法,采用依托Liunx开发环境,在介绍完基本概念之后,直接从实际的问题入手讲解,也就是说是“倒过来讲”。因为我们依托的是Linux环境,我们使用的C库其实是GNU C。

Linux开发环境搭建

现在可以使用WSL + VS Code Remote来搭建windows与Linux的交叉开发环境,各位如果喜欢这种新的方式可以移步这里。我下面要介绍的是用PC机win10+虚拟机64位Ubuntu 14.04+Source insight, smba来搭建。

首先安装VMware,下载Ubuntu镜像文件,ubuntu-14.04.5-desktop-amd64.iso。新建虚拟机,根据需要选择磁盘容量之后,点击完成。

修改虚拟机设置,根据后续需要设置虚拟机内存大小,在 CD/DVD(SATA)项,选择光盘提供的 ubuntu-14.04.5-desktop-amd64.iso 镜像文件。网络选择桥接模式。点击运行之后,按步骤安装Ubuntu即可。


按住键盘Ctrl + Alt + t ,打开一个命令解析器,输入sudo passwd root,添加一个root密码,这儿密码配置成1。设置开机时可以选择root 登录,执行命令gedit /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf,打开编辑50-unity-greeter.conf 文件,在打开文件中添加如下信息,来设置登录时可以选择用户登录,如下图所示:

然后再在shell终端输入命令gedit /root/.profile,添加tty -s &&信息,如下

点击保存,重启后既可以选择root登陆了。


为了方便在windows主机编辑代码,可以安装samba服务器,当然,如果您使用Vim比较熟悉的话,作为嵌入式工程师直接用Vim修改系统代码即可。输入命令apt-get install samba smbclient,遇提示[Y/n]敲回车默认安装。修改配置文件,编辑smb.conf 文件:vi /etc/samba/smb.conf。在配置文件的最末尾加上下面内容:

设置Samba用户和密码,命令smbpasswd -a root 接着按提示输入密码,重新启动samba服务,命令/etc/init.d/samba restart,查看Ubuntu ip地址,命令ifconfig:

最后在电脑-计算机-下右键添加一个网络位置,输入:\\上面查看的ip地址\share,点击下一步

修改网络名称,点击下一步,按提示输入Samba用户名密码,点击确定。

成功完成Samba共享访问后,会看到Ubuntu系统下Samba共享的文件夹。

PS:上面共享目录是整个Ubuntu系统的目录,我们一般只需要访问/home下目录,所以需要修改目录对应的权限如修改qihua目录权限,命令chmod 777 /home/qihua/ 。


在这里说一下Linux下的编译器:gcc。gcc的编译过程:C源文件-预处理-编译-汇编-链接-可执行文件。

  • 预处理:gcc -E hello.c > hello.i (重定向保存,预处理文件后缀为.i)

  • 编译:gcc -S hello.i (默认产生后缀为.s的目标文件)

  • 汇编:gcc -c hello.s (默认产生后缀为.o的目标文件)

  • 链接:gcc hello.o -o hello (指定生成可执行文件的名字)

  • 可执行文件:./hello 执行当前目录下的可执行文件hello

当然,我们在实际编译的过程中不需要这样一步一步执行,使用 gcc hello.c -o myhello (指定生成可执行文件的名字)即可将源文件编译成可执行文件,也可以使用make hello ,使用默认makefile生成可执行文件hello。

C基本概念

在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。C中的数据类型可以分为以下几种:

  • 基本数据类型(short;int; long;float;double;char)

  • 构造类型(array;struct;union;enum)

  • 指针类型

  • 空类型(void)

float类型数无法和一确切的数比较是否相等(float类型本身并不精确,),不同形式的0值,数值0,字符'0',字符串"0",转义符0'\0',以及指针空NULL。


常量是在程序执行过程中值不会发生变化的量,包括整型常量,实型常量,字符常量,字符串常量,标识常量。

  • 整型常量:1790,34,56。

  • 实型常量:3.14,2.56,0.67。

  • 字符常量:单引号引起来的单个字符或转义字符,如'a','D','\n','\0','\ddd'(三位八进制数),'\xhh'(两位16进制数) '\015','\x7f','\018'(非法!)。

  • 字符串常量:双引号引起来的一个或多个字符组成的序列,如"helloworld","a",""(空字符串,只有一个'\0'占用一个字节)"abcd\n\021\018"(特殊)。

  • 标识常量:#define,处理在程序预处理阶段,占编译时间,优点是一改全改,缺点是不检查语法,只是单纯的宏体与宏名之间的替换。

变量是用来保存一些特定内容,并且在程序执行过程中值随时会发生变化的量。定义如下图:

  • 标识符:由字母,数字,下划线组成且不能以数字开头的一个标识序列,取标识符尽量做到见名生义。笔者一般采用驼峰命名法,不同公司会有不同的要求。

  • 数据类型:基本数据类型 + 构造类型

  • 值:注意与数据类型匹配,否则会出现精度丢失等问题。

变量可以添加关键字来说明存储类型。

  • auto:默认,自动分配空间,自动回收空间

  • static:静态型,自动初始化为0值或空值,并且其变量的值具有继承性,常用于修饰变量或函数。

  • register:寄存器类型(建议性关键字),register int i = 1; 由编译器决定是否存储在寄存器中, 大小有限制只能用来定义局部变量,32位机器只能定义32位大小的数据类型,如double就不可以,寄存器没有地址,所以无法打印寄存器类型变量的地址进行查看或使用。

  • extern:说明型,不能改变被说明的变量的值或类型。

变量具有生命周期和作用范围,全局变量是作用范围从定义位置开始直到程序结束,变量一直存在于内存中。局部变量的作用范围从申明位置开始直到当前块作用域结束 ,当前块结束后内存资源释放。


C语言包含很多中运算符,参与运算的操作数个数为1的单目运算符,条件运算符,以及赋值运算符。在同一条语句中运算符之间根据优先级排序执行运算顺序。

注意%要求左右操作数必须为整型, == 和 = 的不同区别(别看这个简单,我review别人代码发现过多次这两个用混了),逻辑运算符(&&, ||的短路特性。

作为嵌入式工程师 ,位运算是我们常常需要用到的。

  • 将操作数中第n位置1,其他位不变:num = num | 1 << n;

  • 将操作数中第n位清0,其他位不变:num = num & ~(1 << n);

  • 测试第n位:if(num & 1 << n)

  • 从一个指定宽度为w的数中取出第(m -> n)位:(num << (w-n)) >> (w-n+m)

输入输出与流程控制

从Shell终端输入a, b, c的值,求二次方程的根( , x = (-b +/- sqrt(delta)) / 2a )。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define WEIGHT  3.0e-23
#define KQ 950static void root()
{float a, b, c;float delta;float x1, x2;printf("please enter for a, b, c: \n");scanf("%f%f%f", &a, &b, &c);delta = b*b - 4*a*c;if(delta < 0){fprintf(stderr, "Input error.\n");exit(1);}x1 = (-b + sqrt(delta)) / (2*a);x2 = (-b - sqrt(delta)) / (2*a);printf("x1 = %f\n", x1);printf("x2 = %f\n", x2);return;
}int main()
{root();exit(0);
}

以上代码演示的是格式化输入输出函数,涉及输入/输出的库函数有以下三类:

  • 格式化输入输出函数:int scanf(const char *format, ...);int printf(const char *format, ...)。注意%s作为输入项非常危险,其不会提示越界问题。

  • 字符输入输出函数: int getchar(void); int putchar(int c);

  • 字符串输入输出函数:char *gets(char *s);int puts(const char *s)。gets函数十分危险,可以用fgets,getline替代


百钱买百鸡:鸡翁一,值钱五;鸡母一,值钱三;三鸡雏,值钱一。百钱买百鸡,问鸡翁,鸡母,鸡雏各几只。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static void Buychicken()
{int a, b, c;for(int a = 0; a < 20; a++){for(int b = 0; b <= 33; b++){c = 100 - a - b;if(c % 3 == 0){if(a*5 + b*3 + c/3*1 == 100)printf("🐓 = %d, 母鸡 = %d, 小鸡 = %d\n", a, b, c);}}}return;
}
int main()
{Buychicken();exit(0);
}

以上这个例子for循环和if判断。C语言的流程控制分以下三类:

  • 顺序:语句逐句执行,C语言为面向过程语言,语句顺序执行。

  • 选择:出现一种以上情况,if....else;switch....case。

  • 循环:语句块循环执行,while;do....while;for;if....goto。

还有一些辅助控制的关键字,像是continue不执行下面的语句,回到循环开始;break跳出循环。

指针与函数

"follow me", "basic", "great", "hello", "hi"五个字符串根据strcmp()比较结果进行排序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char* name[5] = {"follow me", "basic", "great", "hello", "hi"};char* tmp = NULL;int flag = 0, num;for(int i = 0; i < 5; i++){printf("%s\n", name[i]);}for(int i = 0; i < 4; i++){for(int j = i+1; j < 5; j++){if(strcmp(name[j], name[i]) < 0){flag = 1;num = j;}}if(flag){flag = 0;tmp = name[i];name[i] = name[num];name[num] = tmp;}}printf("\nafter sort:\n\n");for(int i = 0; i < 5; i++){printf("%s\n", name[i]);}exit(0);
}

上面这个例子涉及到字符串的存储,要使用一个“hello”字符串,有如下两种方式:

  • char *str = "hello"; str = "world"; puts(str);

  • char str[] = "hello"; strcpy(str, "world"); puts(str);

指针作为C语言中最为重要的概念,它允许我们直接访问某个地址下的数据,下面是几个涉及指针的关键知识点。

  • 指针分不同数据类型的指针,int * ptr与char *ptr在内存中前者指向一个int类型数据的存储地址(一般为32位),而后者指向的是一个char类型数据的存储空间,ptr++在数值上前者增加了4,而后者增加了1。

  • 指针定义时可以使用空类型void* p = NULL,后边使用*(int *)p,强制类型转换之后再获得指针指向数据。

  • 避免野指针问题,内存空间释放之后记得把指向此空间的指针置为空。

指针还允许我们跳到不同的代码块,这个时候指针的名称叫做函数指针。下面这个例子是一个函数指针的例子:

# include <stdio.h>
int Max(int, int);  //函数声明
int main(void)
{int(*p)(int, int);  //定义一个函数指针int a, b, c;p = Max;  //把函数Max赋给指针变量p, 使p指向Max函数printf("please enter a and b:");scanf("%d%d", &a, &b);c = (*p)(a, b);  //通过函数指针调用Max函数printf("a = %d\nb = %d\nmax = %d\n", a, b, c);return 0;
}
int Max(int x, int y)  //定义Max函数
{int z;if (x > y){z = x;}else{z = y;}return z;
}

指针变量本身也是存在内存的数值,那么指向指针变量的地址就是二级指针,有些面试题喜欢拿这个“套娃”知识点做题,我就不详述了。


在讲函数之前,我简单介绍一下makefile,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。下面是一个makefile的最简单形式,它告诉编译make工具使用maic.c和tool.c来生成mytool可执行文件:

OBJS=main.o tool.o
CC=gcc
RM=rm -f
CFLAGS+=-c -Wall -gmytool:$(OBJS)$(CC) $^ -o $@%.o:%.c$(CC) $^ $(CFLAGS) -o $@clean:$(RM) *.o mytool -r

下面是一个函数的定义,它在tool.c中定义,它的形式如下图所示:

#include <stdio.h>#include "tool.h"void mytool()
{printf("tool print\n\n");
}

下面是main.c的内容,main()函数调用了mytool()函数:

#include <stdio.h>
#include <stdlib.h>#include "tool.h"int main()
{mytool();exit(0);
}
  • 函数的传参分为通常所用的值传递,即为函数内部使用的入参为原始数据的副本,还有地址传递,这个时候就可以通过地址来改变原始数据的值。

  • 函数的调用分为正常的嵌套调用和递归调用,嵌套调用就是函数调用别的函数再调用别的函数,嵌套的级数越多对系统资源消耗越大。递归调用就是自己调用自己。

数组与构造类型

数组作为最常见的构造类型。下图是一个二维数的形式:

下面是利用二维数组来实现的矩阵乘法:

#include <stdio.h>
#include <stdlib.h>#define M   2
#define N   3
#define K   2static void multiply()
{int a[M][N] = {1,2,3,4,5,6};int b[N][K] = {1,0,0,1,1,0};int c[M][K] = {0};for(int i = 0; i < M; i++){for(int j = 0; j < K; j++){for(int k = 0; k < N; k++){c[i][j] += a[i][k] * b[k][j];}}}for(int i = 0; i < M; i++){for(int j = 0; j < K; j++){printf("%d\t", c[i][j]);}printf("\n");}return;
}int main()
{multiply();exit(0);
}

C标准库提供了一系列字符数组的操作函数,包括:strlen & sizeof; strcpy & strncpy;strcat & strncat;strcmp & strncmp。


我们常见的构造体类型是结构体,当遇到大型软件的时候,最难梳理的往往就是结构体之间的关系。下面是一个结构体的例子,非常简单我就不说语义了,我提一个问题,最后打印的两个sizeof分别是多少?加不加"__attribute__((packed))"对结果有什么影响?知道答案的可以在评论区留言。

struct simple_st
{int i;float f;char ch;
};    //__attribute__((packed));
void func(struct simple_st b)
{printf("size of b = %lu\n", sizeof(b));
}void func2(struct simple_st *p)
{printf("size of p = %lu\n", sizeof(p));
}
int main()
{//TYPE NAME = VALUE;struct simple_st a;struct simple_st *p = &a;func(a);func2(p);
}

比较少用到的就是共用体了,它是允许你通过不同的结构去理解同一片存储区域。你可以看到这个共用体的大小由最大的成员决定。

#include <stdio.h>
#include <stdlib.h>union test_un
{int i;float f;double d;char ch;
};int main()
{union test_un a;union test_un *p = &a;union test_un arr[3];a.f = 345.678;printf("size of a = %lu\n", sizeof(a));printf("a.f = %f\n", a.f);printf("p->f = %f\n", p->f);//printf("a.i = %d\n", a.i);exit(0);
}

共生体一般会和位域配合使用,能够给使用者提供针对某一个完整数据类型其中某个位段数据的操作,这在车载领域的CAN报文应用广泛,我们可以根据DBC定义的Message编写对应的联合体定义,针对其不同的Signals赋值之后就可以通过CAN控制器发送报文。

union add_un
{struct{unsigned short a;unsigned short b;}n;unsigned int c;
};int main()
{unsigned int i = 0x11223344;union add_un a;//printf("0x%x\n", ((i >> 16) + (i & 0x0000FFFF)));a.c = i;printf("0x%x\n", a.n.b);printf("0x%x\n", a.n.a);printf("0x%x\n", a.n.a + a.n.b);exit(0);
}

最后,聊聊枚举。不要以为枚举有什么好讲的,如果你阅读过Linux内核的代码,你就会发现它大量的使用了宏定义以及枚举等预编译技术,它们虽然会带来编译时长的增加,但是却会带来诸如易读以及执行速度的优势。

#include <stdio.h>
#include <stdlib.h>enum day
{MON = 1,    //默认从0开始往下排TUS,WES,THR,FRI = 1,SAT,SUN
};enum    //当作宏来使用
{STATE_RUNNING = 1,STATE_CANCELLED,STATE_OVER
};struct job_st
{int id;int state;time_t start, end;
};int main()
{struct job_st job1;job1.state = STATE_OVER;switch (job1.state){case STATE_RUNNING:break;case STATE_CANCELLED:break;case STATE_OVER:break;default:break;}#if 0enum day a = SUN;a = TUS;printf("%d\n", a);#endifexit(0);
}

十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

相关文章:

Linux环境C语言开发基础

C语言是一门面向过程的计算机编程语言&#xff0c;与C、C#、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言诞生于美国的贝尔实验室&#xff0c;由丹…...

string类(上)

string类&#xff08;上&#xff09;1.标准库中的string类2.string类对象的常见构造①string()②string(const char* s)③string(size_t n,char c)④string(const string&s)⑤string(const string& str,size_t pos,size_t lennpos)⑥string&#xff08;const char* s,s…...

ElasticSearch快速入门详解(亲测好用,强烈推荐收藏)

3.快速入门 接下来快速看下elasticsearch的使用 3.1.概念 Elasticsearch虽然是一种NoSql库&#xff0c;但最终的目的是存储数据、检索数据。因此很多概念与MySQL类似的。 ES中的概念数据库概念说明索引库&#xff08;indices)数据库&#xff08;Database&#xff09;ES中可…...

出入了解——Vue.js

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。座右铭&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石&#xff0c;故能成其高。个人主页&#xff1a;小李会科技的…...

MySQL8 双主(主主)架构部署实战

前言 大家好&#xff0c;我是 沐风晓月 本文收录于《数据库入门到精通系列》专栏&#xff0c; 更多内容可以关注我的csdn博客。 本文主要讲解MySQL主主架构实战,在开始之前需要根据下面的提示来配置环境&#xff1a; Linux基础命令不熟参考&#xff1a; 《linux基本功-基础…...

【数据结构】第三站:单链表

目录 一、顺序表的缺陷 二、链表 1.链表的概念以及结构 2.链表的分类 3.单链表的逻辑结构与物理结构 三、单链表的实现 1.单链表的定义 2.单链表的接口定义 3.单链表的接口实现 四、单链表的实现完整代码 一、顺序表的缺陷 在上一篇文章中&#xff0c;我们了解了顺序…...

【蓝桥杯2020】七段码

【题目描述】 七段码 HUSTOJ 题目导出文件 [蓝桥杯2020] 第十一届蓝桥杯第二次省赛—填空题E题 七段码 小蓝要用七段码数码管来表示一种特殊的文字。 上图给出了七段码数码管的一个图示&#xff0c;数码管中一共有 7 段可以发光的二 极管&#xff0c;分别标记为 a, b, c,…...

Spark读取JDBC调优

Spark读取JDBC调优&#xff0c;如何调参一、场景构建二、参数设置1.灵活运用分区列实际问题&#xff1a;工作中需要读取一个存放了三四年历史数据的pg数仓表&#xff08;缺少主键id&#xff09;&#xff0c;需要将数据同步到阿里云 MC中&#xff0c;Spark在使用JDBC读取关系型数…...

【文心一言】什么是文心一言,如何获得内测和使用方法。

文心一言什么是文心一言怎么获得内测资格接下来就给大家展示一下文学创作商业文案创作数理逻辑推算中文理解多模态生成用python写一个九九乘法表写古诗前言&#xff1a; &#x1f3e0;个人主页&#xff1a;以山河作礼。 &#x1f4dd;​&#x1f4dd;:本文章是帮助大家了解文心…...

CentOS8服务篇10:FTP服务器配置与管理

一、安装与启动FTP服务器 1、安装VSFTP服务器所需要的安装包 #yum -y install vsftpd 2、查看配置文件参数 Vim /etc/vsftpd/vsftpd.conf &#xff08;1&#xff09;是否允许匿名登录 anonymous_enableYES 该行用于控制是否允许匿名用户登录。 &#xff08;2&…...

笔试强训3.14

一、选择题 1.以下说法错误的是&#xff08;C&#xff09; A.数组是一个对象 B.数组不是一种原生类 C.数组的大小可以任意改变 D.在Java中&#xff0c;数组存储在堆中连续内存空间里 ​ 相关知识点&#xff1a;原生/内置数组是那八个&#xff0c;其他的都是引用的&#xff0c;借…...

elasticsearch 环境搭建和基本操作

参考资料 适合后端编程人员的elasticsearch快速实战教程 ElasticSearch最新实战教程 ElasticSearch配套笔记 自制搜索引擎 https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup.html restful风格的api REST 设计风格 例如以下springboot示例 RestContr…...

IDEA操作:Springboot项目打包为jar包并运行

在IDEA环境下对Springboot项目打包为jar包且在terminal运行操作 1、 2、 3、注意&#xff1a;在项目目录里创建一个用来存放jar包的文件夹&#xff08;res&#xff09;,该路径不能使用IDEA设置的默认路径&#xff0c;必须手动创建。 4、 5、点击ok后加载运行包 &#xff08;8…...

原理底层计划---JVM

二、JVM对空间大小怎么配置&#xff1f;各区域怎么划&#xff1f; 新生代&#xff1a;短时间生成&#xff0c;可以马上回收 老生代&#xff1a;少部分对象会存在很久&#xff0c;回收策略应不同 三、JVM哪些内存区域会发生内存溢出&#xff08;程序计数器不会&#xff09; …...

CSDN-猜年龄、纸牌三角形、排他平方数

猜年龄 原题链接&#xff1a;https://edu.csdn.net/skill/practice/algorithm-a413078fb6e74644b8c9f6e28896e377/2258 美国数学家维纳(N.Wiener)智力早熟&#xff0c;11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。 一次&#xff0c;他参加某个重要会议&#xf…...

【Linux】软件包管理器 yum

什么是软件包和软件包管理器 在 Linux 下需要安装软件时&#xff0c; 最原始的办法就是下载到程序的源代码&#xff0c; 进行编译得到可执行程序。但是这样太麻烦了&#xff0c;所以有些人就把一些常用的软件提前编译好, 做成软件包 ( 就相当于windows上的软件安装程序)放在服…...

一天吃透TCP面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

zzu天梯赛选拔

C. NANA去上课 — 简单数学 需要记录上一步处在哪个位置 然后判断如果是同一侧移动距离就是abs&#xff08;x1 - x2&#xff09; 如果不同就是x1 x2 #include <iostream> #include <cmath> using namespace std; #define int long long signed main() {int n; c…...

【C语言】一篇让你彻底吃透(结构体与结构体位段)

本章重点 主要讲解结构体和位移动的使用和定义与声明&#xff0c;并且结构体和位段在内存中是如何存储的。 文章目录结构体结构体类型的声明结构体特殊的声明结构体变量的定义和初始化结构体成员的访问结构的自引用结构体内存对齐结构体传参位段什么是位段位段的内存分配位段的…...

数据结构之二叉树构建、广度/深度优先(前序、中序、后序)遍历

一、二叉树 1.1 树 说到树&#xff0c;我们暂时忘记学习&#xff0c;来看一下大自然的树&#xff1a; 哈哈 以上照片是自己拍的&#xff0c;大家凑合看看 回归正题&#xff0c;那么在数据结构中&#xff0c;树是什么呢&#xff0c;通过上面的图片大家也可以理解 树是一种非…...

“国产版ChatGPT”文心一言发布会现场Demo硬核复现

文章目录前言实验结果一、文学创作问题1 :《三体》的作者是哪里人&#xff1f;问题2&#xff1a;可以总结下三体的核心内容吗&#xff1f;如果要续写的话&#xff0c;可以从哪些角度出发&#xff1f;问题3&#xff1a;如何从哲学角度来进行续写&#xff1f;问题4&#xff1a;电…...

202304读书笔记|《不被定义的女孩》——做最真实最漂亮的自己,依心而行

202304读书笔记|《不被定义的女孩》——做最真实最漂亮的自己&#xff0c;依心而行《不被定义的女孩》作者ASEN&#xff0c;很棒的书。处处透露着洒脱&#xff0c;通透&#xff0c;悦己&#xff0c;阅世界的自由的氛围和态度&#xff01; 部分节选如下&#xff1a; 让自己活得…...

SpringBoot帮你优雅的关闭WEB应用程序

Graceful shutdown 应用 Graceful shutdown说明 Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and servlet-based web applications. It occurs as part of closing the applica…...

递归与递推

递归 直白理解&#xff1a;函数在其内部调用自身&#xff08;自己调用自己&#xff09;所有递归都可以采用递归搜索树来理解递归的特点&#xff1a; 一般来说代码较为简短&#xff0c;但是理解难度大一般时间和空间消耗较大&#xff0c;容易产生重复计算&#xff0c;可能爆栈 …...

使用<style scoped>导致的样式问题

问题描述&#xff1a; 今天使用开源组件库TDesign的自动补全组件时&#xff0c;遇到了一个样式失效问题&#xff0c;一开始怎么也找不到问题出在哪&#xff0c;后面一个偶然去掉了scoped&#xff0c;竟然发现样式竟然正常了&#xff0c;具体原因不知道在哪&#xff0c;有大佬知…...

Elasticsearch深入理解(十八)-集群关键指标及调优指南

1、CPU使用率 CPU使用率是指在一段时间内CPU执行程序的百分比&#xff0c;它是衡量系统资源利用率的一种指标。 1.1 详细说明&#xff1a; 在Elasticsearch中&#xff0c;高的CPU使用率通常意味着节点正在执行大量的计算任务&#xff0c;这可能是因为索引和搜索操作的负载较大…...

Transformer到底为何这么牛

从注意力机制&#xff08;attention&#xff09;开始&#xff0c;近两年提及最多的就是Transformer了&#xff0c;那么Transformer到底是什么机制&#xff0c;凭啥这么牛&#xff1f;各个领域都能用&#xff1f;一文带你揭开Transformer的神秘面纱。 目录 1.深度学习&#xff0…...

【Spring事务】声明式事务 使用详解

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 声明式事务一、编程式事务二、声明式事务&…...

学习28个案例总结

学习前 对于之前遇到的问题没有及时总结&#xff0c;导致做什么事情都是新的一样。没有把之前学习到接触到的内容应用上。通过这次对28个案例的学习。把之前遇到的问题总结成自己的经验&#xff0c;在以后的开发过程中避免踩重复性的坑。多看帮助少走弯路。 学习中 对28个案例…...

刷题Java常用方法总结

刷题Java常用方法总结 文章目录刷题Java常用方法总结快速查看:静态数组 Static Array初始化instance属性length技巧Arrays.sort从小到大排序Arrays.fill填满一个数组Arrays.copyOf / arr.clone()复制一个数组(二维数组也可以)动态数组 List & Dynamic Array初始化常规 - Ar…...