C语言深度剖析 -- 32个关键字(上)

news2024/11/17 20:39:18

文章目录

    • C语言关键字
    • 我们人生中第一个C语言程序
    • 变量的定义与声明
    • 变量的作用域与生命周期
    • 最宽宏大量的关键字 -- auto
    • 最快的关键字 -- register(寄存器变量)
    • 最名不符实的关键字 -- static
    • 基本内置数据类型 -- char、short、int、long、float、double
    • 最冤枉的关键字 -- sizeof
    • signed、unsigned关键字(整形在内存中的存储)
  • 这一节,我们就讲到这里了,下面一直会持续学习的,大家一起加油
  • 努力提升自己,永远比仰望别人更有意义

C语言关键字

我们都知道C语言关键字有auto、if、int等等…但是我们知道C语言一共有多少个关键字呢?
一般来说,共有32个关键字(C90或C89标准);
但是后面C99又新增了5个关键字;但是目前主流的编译器,对C99好多并不支持;
所以,我们默认按照C90标准,即C语言共有32个关键字;

关键字说明
auto声明自动变量
short声明短整型变量或函数
int声明整形变量或函数
long声明长整型变量或函数
float声明单精度浮点数变量或函数
double声明双精度浮点数或函数
char声明字符型变量或函数
struct声明结构体变量或函数
union声明共用数据类型
enum声明枚举类型
typedef用以给数据类型取别名
const声明只读变量
unsigned声明无符号变量或函数
signed声明有符号变量或函数
extern声明变量是在其他文件中声明
register声明寄存器变量
static声明静态变量
volatile说明变量在程序执行中可被隐含的改变
void声明函数无返回值或无参数,声明无类型指针
if条件语句
else条件语句与分支语句(与if合用)
switch用于开关语句
case开关语句分支
for循环语句
do循环语句的循环体
while循环语句的循环条件
goto无条件跳转语句
continue结束当前一层循环,开始下一轮循环
break跳出当前循环
default开关语句中的“其他”分支
sizeof计算数据类型长度
return子程序返回语句循环条件(可带参数,也可不带)

我们人生中第一个C语言程序

//从vs中创建c语言项目
#include <stdio.h>
#include <windows.h>//此头文件仅仅是为了停屏

int main()
{
    printf("hello world!\n");
    system("pause");//pause停屏,我们可以看到终端
    return 0;
}

在windows系统中,我们双击的本质就是运行程序,将程序添加到内存当中
任何程序在运行之前都必须加载到内存当中
注意: 程序在没有加载的时候,是放在硬盘当中的;我们之所以加载到内存当中 -》快;
在这里插入图片描述

变量的定义与声明

  • 问题1:什么是变量?—在 内存中 开辟特定大小的空间,用来保存数据

  • 问题2:如何定义变量:类型 变量名 = 默认值;例如: int a = 10; double d = 3.14; char c = 'a';

  • 问题3:为什么要定义变量?—

计算机的诞生就是为了解决人类计算能力不足的问题;即计算机就是为了计算的。
而计算,就需要数据;
我们计算数据,并不是无时无刻都需要计算;例如:我们吃饭并不是所有饭菜都立刻吃掉的,我们需要碗和盘子,把饭菜放到里面,想吃的时候就吃;
那么,有人就会抬杠:为什么要盘子,不可以直接使用在锅里吃吗?可以,但是 效率低
总之:我们定义变量是为了在我们想用的时候可以立即拿出,不用的时候就放在那就可以了

  • 问题4:变量定义的本质?— 我们现在知道了:程序运行之前,我们需要把数据加载到内存当中,程序计算时,需要使用到变量;那么, 定义变量的本质就是在内存中开辟一片空间,用来保存数据
  • 问题5:变量声明的本质?— 我们举个例子:比如你和你的兄弟都喜欢一个女孩子翠花,但是你的胆子大,你就直接和翠花表白,翠花答应你了,这时候,你就可以告诉那个兄弟:翠花现在是我的女朋友,现在你们要保持距离。-》这里,表白就是定义,你和你兄弟说就是声明;声明的本质也就是广而告之

总结: 变量的定义:开辟空间的,定义只能定义一次(你不可能和翠花表白很多次,别人会被你吓跑的);变量的声明是告之,可以声明很多次;但是在声明的时候,我们就不可以进行赋值操作了(编译器会有可能把这个过程看成是定义过程)

变量的作用域与生命周期

  1. 作用域:指的是该变量可以被正常访问的代码区域(改变量的有效区域);这里我们需要知道:全局变量在整个程序运行期间都有效;局部变量只在本代码块内有效(用 {} 括起来的区域,就叫做代码块)
#include <stdio.h>
#include <windows.h>

int g_x = 100;//全局变量

int main()
{
    int x = 10;
    if (x)
    {
        int y = 20;//局部变量
        //y只能在代码块内有效,而全局变量g_x在哪里都有效
        printf("局部变量 y = %d, 全局变量 g_x = %d\n", y, g_x);
    }
    //printf("局部变量 y = %d\n", y);//错误,局部变量只在本代码块内有效
    
    system("pause");
    return 0;
}
  1. 生命周期:指的是改变量从定义到被释放的时间范围;全局变量:定义完成之后,程序运行的整个生命周期内,改变量一直有效;局部变量:进入代码块,形成局部变量,退出代码块,释放局部变量,生命周期结束;
  2. 作用域 VS 生命周期:例如:爱迪生对世界的贡献很大,爱迪生的生命周期就是从出生到死亡,而他并不是一直对世界作出贡献,他做出贡献的时间才是作用域

在这里插入图片描述

最宽宏大量的关键字 – auto

在c语言中,auto的用法很少且比较鸡肋,用处不大;但是在 C++ 中给auto赋予了很多的用处(配合STL);但是在C语言里面我们就暂且不说C++的知识了;

auto这个关键字一般是用来 修饰局部变量的 ,默认情况下都是auto修饰的(局部变量、自动变量、临时变量我们统称为局部变量)

#include <stdio.h>
#include <windows.h>

int main()
{
	for (auto i = 1; i < 10; i++)
	{
		printf("i = %d\n", i);
		if (1)
		{
			auto j = 0;//局部变量,这一个代码块结束之后,j又被赋值成0
			printf("before: j = %d\n", j);
			j += 1;
			printf("after: j = %d\n", j);//j是0/1循环的
		}
	}

	system("pause");
	return 0;
}

注意:这里面的auto都是可以省略的,在C语言中我们可以忽略这个关键字

最快的关键字 – register(寄存器变量)

我们学习过计组的话,就会知道计算机的系统结构;其中,CPU主要负责计算相关的硬件单元,但是为了方便计算,(解决CPU与内存之间速度差异的问题)一般第一步需要把数据从内存中读取到CPU中,也就是需要CPU具有一定的存储能力;注意:CPU可能并不是需要计算当前读入到里面的数据,只是为了提前存储好,想用就可以用了,不然的话,速度太慢了;
我们来看一下CPU存储金字塔:

在这里插入图片描述

距离CPU越近的存储硬件,速度越快

  • 问题1:什么是寄存器? – 如果我们学过计组的话,就会很清楚的明白,但是如果我们还没有学的时候,我们只需知道CPU内部集成了一组存储硬件,这组硬件叫做寄存器即可
  • 问题2:寄存器存在的本质? – 提高计算机的运行效率,就不需要从内存中读取数据了
  • 问题3:什么样的变量适合使用寄存器变量呢?
  1. 局部的(全局变量会导致CPU寄存器被长时间占用)
  2. 不会被写入的(写入需要回内存,后续还要读取检测的话,register就没有意义了)
  3. 高频率读取的(提高效率)
  4. 寄存器数量有限,不可以大量使用register关键字

注意:除了以上的内容,还有就是:register修饰的变量不可以取地址(地址是内存相关的概念)

demo:

#include <stdio.h>
#include <windows.h>

int main()
{
	register int a = 10;
	printf("&a = %p\n", &a);//报错 -- C2103	寄存器变量上的“& ”
	
	system("pause");
	return 0;
}

最名不符实的关键字 – static

在讲这个关键字之间,我们之前应该了解到,我们自己在写C语言项目的时候,项目会非常大且复杂,我们一般都是会写很多了源文件(.c文件)和一个头文件(.h);我们把所有用到的函数、变量、头文件、#define、struct、typedef等等都会放到 .h(头文件) 文件中,这样可以大大减少项目的维护成本;这里面又会牵扯到头文件重复包含的问题,我们先给一个解决方案,后面还会细讲#pragma once

我们先提一下extern这个关键字,当我们想跨源文件来使用某个变量或函数的时候,就必须使用到这个关键字例如:extern int g_val;函数可以直接在头文件声明,不需要使用 extern,但是最好也带上extern void show();

总结:变量声明必须带上extern,函数声明建议带上extern变量不可以跨文件访问,而函数可以跨文件访问

static的作用

  1. 修饰全局变量的时候,该全局变量只能在本文件内被使用,不可跨文件访问,也就是更改变量的作用域
  2. 修饰函数的时候,该函数只能在本文件内被使用,不可跨文件访问,也就是更改变量的作用域
  3. 修饰局部变量的时候,会更改局部变量的生命周期(不是作用域)

demo:

#include <stdio.h>
#include <windows.h>

void fun1()
{
	int i = 0;
	i++;
	printf("no static: i = %d\n", i);//输出10个1
}

void fun2()
{
	static i = 0;
	i++;
	printf("has static: i = %d\n", i);//输出1-10;更改了i的生命周期
}

int main()
{
	for (int i = 0; i < 10; i++)
	{
		//fun1();
		fun2();
	}

	system("pause");
	return 0;
}

总结:static修饰局部变量,变量的生命周期会变成全局周期(作用域不变)

补充一下C语言寻址空间的知识

在这里插入图片描述

基本内置数据类型 – char、short、int、long、float、double

基本数据类型有以下几种:

在这里插入图片描述

我们这里先讲解基本的内置类型:

这里,我们只需要搞懂一个问题:为什么语言要有好多种数据类型,直接将内存整体使用不好吗?
在任何时候,都不是只有我们当前的程序在运行,还有其他很多种程序在运行,你把这块内存占用了,其他的程序并不知道你正在使用这块内存,他不知道是不是可以使用;还有,你把这块内存全用了,你的程序并不是无时无刻都在使用,当不需要使用的时候,你就是在浪费这块内存了;
做月饼的例子:月饼的外表有各种各样的,我们只需要使用不同的模子就可以制造出各种各样的月饼了;
在这里插入图片描述
所以,C语言中,为什么有那么多的类型,就是为了满足不同的场景
比如:我们想计算我们的工资的时候,4个字节的int就足够了,没有必要开大

那么,我们这里就需要知道,这些类型到底在内存中占用多少内存大小呢?

在这里插入图片描述

注意:上面的单位都是字节

最冤枉的关键字 – sizeof

我们为什么称sizeof为最冤枉的关键字?就是因为常年别人都把他误认为是函数,这是错误的,sizeof是C语言中的关键字
我们只需要记住sizeof是计算类型或变量在内存中占多大空间的就可以了,上面我们已经计算过了,至于sizeof与指针的内容,我们会在后面指针的部分讲到;

注意1:

int a = 10;
printf("%d\n", sizeof(a));//对
printf("%d\n", sizeof a);//对
printf("%d\n", sizeof(int));//对
printf("%d\n", sizeof int);//错误

注意2:sizeof后面的括号里是不允许有其他操作的,就算写也不起效果

int a = 10;
printf("%d\n", sizeof(a++));
printf("%d\n", a);//a还是10

signed、unsigned关键字(整形在内存中的存储)

浮点数(float、double)都是有符号的,浮点数没有unsigned

我们需要先理解原码、反码、补码的概念:

  1. 计算机中的有符号数有三种表示方法,原码、反码、补码
  2. 三种表示方法均有符号位与数值位,符号位都是用0表示正,1表示负,位数值位的表示各不相同
  3. 正数与无符号数(unsigned)的原码、反码、补码都相同
  4. 负数原码:直接将二进制按照正负数的形式翻译成二进制就可以了
  5. 负数反码:将原码的符号位不变,其他为按位去反就可以了
  6. 负数补码:反码+1就得到补码
  7. 对于整形来说:数据存放内存中其他存放的是补码(后面会讲)

我们知道,一个变量的创建是现在内存中开辟空间的,空间的大小是由类型决定的
那么,数据开辟好了空间,在内存中到底是怎样存储的呢?
在这里插入图片描述

我们在定义类型的时候,默认前面省略了 signed

我们现在来看个问题?unsigned int b = -10;这个写法是否正确呢?
答案?这样写是没有问题的,是正确的的;整形在存储的时候,是不关心内容的

在这里插入图片描述
我们来看下面这个例子:

在这里插入图片描述
我们a虽然是有符号的整形,但是我们取出来的时候,按照有符号的整形打印他就是-10,而我们把它当成无符号的整形取出来的时候,就是那个值了;同理b;所以我们发现:我们定义变量,给他类型,只是给他开辟了特定的空间,到底存放什么内容我们不用管,但是取出来的时候,我们就必须看他是什么类型,或者你按照什么类型给他取出来的

下面还有几个小的知识点,我们来看看吧~

  1. 我们知道了原码怎么转向补码的,但是我们怎么反过来把补码转成原码呢?在这里插入图片描述
  2. 二进制快速转化口诀:在这里插入图片描述

到这里,我们已经知道了我们的数据是存放到内存里面,按照补码形式进行存储的,那么我们来看一下到底是怎样存的呢?
我们以int a = 10;来看一下

在这里插入图片描述
我们发现在vs中,我们的变量最后在内存中是这样存储的,我们来分析一下?

10的补码是:0000 0000 0000 0000 0000 0000 0000 1010
在计算中存储的是十六进制:0x00 00 00 0A
为什么我们在内存中看到的是反过来的呢?0x0a 00 00 00

这里我们需要了解大小端的概念:我们定义好变量后,会开辟一片空间,将变量的二进制补码写入到内存中,那么我们如何写进去呢?是从前往后写,还是从后往前写呢?这里没有特定的要求,不管我们怎么放,只要使用同等的条件去取就可以了?由此,产生了两种不同的厂商,分为大端和小端,目前比较流行的是小端。

在这里插入图片描述

对于大小端这件事,对于每个人是无法达到一致的,每个人都有每个人的看法,我们都没有足够的理由说服对方;
对于数据的存与取,我们除了要看上面我们学的看数据类型,这里还要加一个看是使用大端存储,还是小端存储不管哪种存储方式,我们只要使用同等条件去取,都可以!

我们怎么判别我们电脑使用大端还是小端呢?(2015年百度一道笔试题)

#include <stdio.h>
#include <windows.h>

int check_sys()
{
	int i = 1;
	return (*(char*)&i);
}

int main()
{
	int ret = check_sys();
	if (ret == 1) printf("小端\n");
	else printf("大端\n");
	system("pause");
	return 0;
}

上面输出的结果是小端;我们来解释一下return (*(char*)&i);这一段代码:我们知道 i 放到内存中的十六进制数是:0x01 00 00 00;我们只需要看 i 的第一个字节内容,如果是1就是小端,如果是0就是大端;那么我们怎么才可以拿到 i 的第一个字节呢?char* 的指针正好就是访问一个字节的地址,我们完整的代码就是:

int i = 1;
char* p = (char*)&i;
if(*p == 1) printf("小端\n");
else printf("大端\n");

为什么变量采用的都是补码来进行存储?

  • 在计算机系统中,数值一律采用补码来表示和存储。原因在于:使用补码,可以将符号位和数值位统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)。此外,补码和原码的相互转换,其运算过程是相同的,不需要额外的硬件电路。

整形取值范围(很重要)
简单为例,我们就以 signed char 为例,其它的和这类似!

在这里插入图片描述
那么为什么 1000 0000 就表示成-128呢?我们来看看char c = -128;在内存中表示多少

在这里插入图片描述
我们可以发现char类型是可以存放-128这个数据的,而128就不可以,这是为什么呢?

在这里插入图片描述
我们可以总结一下各种数据类型的取值范围:

  • char: [-2 ^ 7, 2 ^ 7 - 1]
  • short: [-2 ^ 15, 2 ^ 15 - 1]
  • int: [-2 ^ 31, 2 ^ 31 - 1]

好了,到这里我们整形数据存储的知识就学的就差不多了,我们来做几个题目检验一下成果吧!

例题一:

#include <stdio.h>
#include <windows.h>


int main()
{
	char a[1000];
	for (int i = 0; i < 1000; i++) a[i] = -1 - i;
	printf("%d\n", strlen(a));
	system("pause");
	return 0;
}

第一点:我们首先要知道 strlen 这个库函数是计算字符串长度的,遇到 ‘\0’ 截至,并且 ‘\0’ 不计算在长度内;'\0’对应的ASCII码值就是0。例如:char a[5] = {3, ‘h’, 5, 0, ‘e’};则 strlen(a)的答案就是3,只计算0前面的字符串长度,且0不包括在内。

第二点:我们需要知道当变量取值范围超过最大值时,之后的值该是多少?

在这里插入图片描述
因此,这道题的答案就是255!

例题二:

#include <stdio.h>
#include <windows.h>


int main()
{
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
	system("pause");
	return 0;
}

在这里插入图片描述

例题三:

#include <stdio.h>
#include <windows.h>


int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--) printf("%u\n", i);
	system("pause");
	return 0;
}

这个题我们要注意:i是个无符号整形变量,打印的时候,会依次打印9 、8、7、6、5…0,当打印到0的时候,i 再减1,就相当于 i + (-1);也就是:
在这里插入图片描述
这个数按照 unsigned int 来打印的话就是 2 ^ 32 - 1 那么大
其实变量的取值范围就是按照之前我给大家画的那个圆来记,以 signed char 来说:
在这里插入图片描述

当变量取到头的时候,会再循环一圈,以此类推…

还有我们在定义unsigned类型的时候,最后最好加个 u,就像定义 float类型在后面加个 f一样,例如:unsigned int u = 10u;

还有一点,大家在这里的时候,记得与整形提升不要搞混淆

在这里插入图片描述
c前面的 c + 1会把char类型的变量整形提升到 int 型,再进行加法运算
整形提升:在表达式计算时,各种整形首先要提升为 int 类型;表达式的整形运算要在CPU的相应器件内进行,CPU运算器的操作数的字节长度一般是 int 类型的字节长度

这一节,我们就讲到这里了,下面一直会持续学习的,大家一起加油

努力提升自己,永远比仰望别人更有意义

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

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

相关文章

transformers学习笔记2

pipeline快速使用from transformers import pipelineclassifier pipeline("sentiment-analysis") classifier(["Ive been waiting for a HuggingFace course my whole life.","I hate this so much!",] )[{label: POSITIVE, score: 0.959804713…

概述.runoob.html

<!DOCTYPE html> 声明为 HTML5 文档<html> 元素是 HTML 页面的根元素<head> 元素包含了文档的元&#xff08;meta&#xff09;数据&#xff0c;如 <meta charset"utf-8"> 定义网页编码格式为 utf-8。<title> 元素描述了文档的标题<…

【Linux线程安全】

Linux线程安全Linux线程互斥进程线程间的互斥相关背景概念互斥量mutex互斥量的接口互斥量实现原理探究可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见的不可重入的情况常见的可重入的情况可重入与线程安全联系可重入与线程安全区别常见锁概念死锁死锁的四…

套接字编程基础

文章目录IPV4套接字地址结构IPv6套接字地址结构字节排序函数地址转换函数IPV4套接字地址结构 IPv4套接字定义在<netinet/in.h> 投文件中&#xff0c;定义如下&#xff1a; struct in_addr {in_addr_t s_addr; } struct sockaddr_in {uint8_t sin_len; // 长度字段sa_fa…

【青训营】性能优化和自动内存管理

本文整理自&#xff1a;第五届字节跳动青年训练营 后端组 什么是性能优化 提高软件系统处理能力&#xff0c;减少不必要消耗&#xff0c;充分利用计算机算力 业务层优化 针对特定场景和具体问题容易获得较大收益 语言运行时优化 面向全公司的优化&#xff0c;非特定场景解决更…

力扣55.跳跃游戏(比较简单)

文章目录力扣55.跳跃游戏&#xff08;比较简单&#xff09;题目描述算法思路代码实现力扣55.跳跃游戏&#xff08;比较简单&#xff09; 题目描述 给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度…

Tailscale-搭建异地局域网开源版中文部署指南

目前国家工信部在大力推动三大运营商发展 IPv6&#xff0c;对家用宽带而言&#xff0c;可以使用的 IPv4 公网 IP 会越来越少。有部分地区即使拿到了公网 IPv4 地址&#xff0c;也是个大内网地址&#xff0c;根本不是真正的公网 IP&#xff0c;访问家庭内网的资源将会变得越来越…

SQL注入之联合查询注入与报错注入

数据来源 本文仅用于信息安全的学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若观众因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与本人无关。 SQL注入之联合查询 sql注入简单演示 1. 判断sq注入 2. 闭合然后爆列 3. 查看显示列 …

vue中实现后台系统权限管理的功能

一、前言 后台管理系统的权限控制对于前端来说是经常用到的知识点&#xff0c;也比较重要&#xff0c;最近梳理一下写成文章&#xff0c;方便以后查阅。 项目中实现菜单的动态权限控制使用到了两种技术&#xff0c;一种是Vue Router&#xff0c;另一种是vue3官方推荐使用的专属…

蓝桥杯嵌入式第十届学习记录

1&#xff1a;拷贝LCD工程代码作为模板2&#xff1a;注意放置代码得顺序3&#xff1a;注意公共头函数键盘4&#xff1a;串口配置出来方便dubug模式正常接收数据5:记得打定时器中断&#xff08;去历程定时器里面寻找&#xff01;&#xff09;6&#xff1a;细节地方7;LCD每个位置…

[hive]数仓分层|用户纬度拉链表|维度建模

https://www.modb.pro/404?redirect%2Fdb%2F241289一、数仓分层1、ODS层&#xff1a;原始数据层ODS(Ooriginal Ddata Sstore)1)设计要点存储来自多个业务系统、前端埋点、爬虫获取的一系列数据源的数据。我们要做三件事&#xff1a;【1】保持数据原貌不做任何修改&#xff0c;…

一阶高通滤波器学习

导读&#xff1a;本期文章主要介绍一阶高通滤波器。一阶高通滤波器与一阶低通滤波器很相似&#xff0c;都是利用电容阻低频信号通高频信号&#xff0c;电感阻高频信号通低频信号的特点。一、一阶高通滤波器介绍滤波器是作为一种选频装置&#xff0c;是信号处理中的一个重要的概…

Linux(二)进程概念

目录 一、冯诺依曼体系结构 二、操作系统 三、进程概念 1、程序与进程的区别&#xff1a; 2、cpu分时机制 3、pcb——进程控制块 4、进程是什么&#xff1f; 四、进程状态 1、linux状态 2、僵尸态 pid_t fork(void)&#xff1a; fork创建进程之后&#xff0c;父子进…

vector以及list

之前已经学习过了string类&#xff0c;接下来介绍c中的另外两个类—— vector和list&#xff1b; vector 之前介绍的string类是c所特定的字符数组&#xff1b; 而vector可以看做是string类的扩展&#xff0c;因为它是一个模板类&#xff1b; 它可以作为任何类型的数组&#x…

小侃设计模式(廿二)-访问者模式

1.概述 访问者模式&#xff08;Visitor Pattern&#xff09;指的是在类的内部结构不变的情况下&#xff0c;不同的访问者访问这个对象都会呈现出不同的处理方式。它的主要作用时将数据结构与数据操作分离&#xff0c;将不同的算法与其所作用的对象进行分离。本文将详述访问者模…

DW动手学数据分析Task2:数据清洗及特征处理

文章目录一 数据清洗1 缺失值观察与处理1.1 缺失值观察1.2 缺失值处理2 重复值观察与处理二 特征处理1 分箱&#xff08;离散化&#xff09;处理2 对文本变量进行转换3 从纯文本Name特征里提取出Titles的特征3 参考文章一 数据清洗 数据清洗&#xff1a;我们拿到的数据通常是不…

树的知识概括锦囊(一)

作者&#xff1a;爱塔居 专栏&#xff1a;数据结构 作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 一、树形结构 二、树的基础知识 三、二叉树 3.1 概念 3.2 特殊的二叉树 ​编辑 3.3 二叉树的性质 四、习题挑战 一、树形结…

手把手教你学51单片机-如何学习单片机

大多数大学生之所以最后变的平庸,不是因为脑子多么笨,也不是全怪自己贪玩不上进,只是没有一个好的领路人,许多学校可能挂着导师的名头,但是多数是挂羊头卖狗肉或者是干脆不管。最后等大学生毕业之后,那些所谓的老师就会说学生很差或者学习很差,反正就是跟自己没啥关系。…

OSPF综合实验(华为)

题目&#xff1a; 思路&#xff1a; 首先配置每个区域的路由和环回地址&#xff0c;其次&#xff0c;根据题目要求打通每个网络的连接&#xff0c;区域0用MGRE打通网络&#xff0c;区域4需要重发布&#xff0c;其次再考虑优化的问题。ip地址的规划是为了更好的路由汇总&#x…

《 Unity Shader 入门精要》第5章 开始 Unity Shader 学习之旅

第5章 开始 Unity Shader 学习之旅 5.2 一个最简单的顶点/片元着色器 顶点/片元着色器的基本结构 // Upgrade NOTE: replaced mul(UNITY_MATRIX_MVP,*) with UnityObjectToClipPos(*)// 定义 shader 的名字 Shader "Chapter 5/Simple Shader" {SubShader{Pass {//…