learn_C_deep_3 (最名不符实的关键字 - static、static关键字总结、基本数据类型、最冤枉的关键字 - sizeof)

news2024/12/30 2:02:26

目录

最名不符实的关键字  -  static

stati修饰全局变量和函数

 static修饰局部变量

static关键字总结

几个问题

1.c语言要设置全局变量和函数可以跨文件使用的原因

2.C程序地址空间是什么样的?

3.局部变量为什么具有临时性

4.全局变量为什么具有全局性

5.为什么static修饰的局部变量生命周期会变长

6.static修饰的局部变量再地址空间会有什么变化吗

基本数据类型

最冤枉的关键字  -  sizeof


最名不符实的关键字  -  static

先来介绍一下多文件

main.c程序源码

#define _CRT_SECURE_NO_WARNINGS 1
//#include<stdio.h>


//extern int g_val;//声明
//extern int g_val = 10;//这样写可以吗? -  error
/*
	在我们没有加入关键字extern的时候,编译器提示
	“g_val”是未声明的标识符,所以我们就需要声明该变量,并不需要
	开辟空间,而我们上面的第二中写法是变量的定义并进行初始化,需要开辟空间
	而我们前面以及在test.c文件中已经开辟过了,而现在再次开辟会多次定义变量。
	这是编译器也提示出了错误:error LNK2005: g_val 已经在 NO2.obj 中定义
							  fatal error LNK1169: 找到一个或多个多重定义的符号

	结论:所有的变量再在声明的时候不可以设置初始值
*/
//int main()
//{
	//show();
	//调用test.c的show函数,在本程序可以使用吗?
	//可以 - 只有警告并为报错
	//warning C4013: “show”未定义;假设外部返回 int

	//printf("%d", g_val); //使用test.c的全局变量g_val,在本程序可以使用吗?
	//不可以
	// error C2065: “g_val”: 未声明的标识符

	//怎么处理呢? - extern关键字
	//printf("%d", g_val);//这样就可以用运行了
//	return 0;
//}

test.c源码

//#include<stdio.h>这里我们也不需要写这句代码啦,在test.h中都包含啦!
#include "test.h"

int g_val = 10;

void show()
{
	printf("hello world!\n");
}

        单纯的使用源文件,组织项目结构的时候,项目越大越复杂,维护的成本也会越来越高,因为我们写的函数或者全局边量会多次被不同的源文件调用而每次调用的时候我们就要声明,这样一个项目将会很复杂,这时我们就需要引用.h结尾的头文件。

头文件在组织项目结构的时候,减少大型项目的维护成本问题。.h基本上都是要被多个源文件包含,但这时可能会有一个问题:头文件会被重复包含

test.h源码

/*
	单纯的使用源文件,组织项目结构的时候,
	项目越大越复杂,维护的成本也会越来越高,
	因为我们写的函数或者全局边量会多次被不同的源文件调用
	而每次调用的时候我们就要声明,这样一个项目将会很复杂
	这是我们就需要引用.h结尾的头文件

	头文件在组织项目结构的时候,减少大型项目的维护成本问题
	.h基本上都是要被多个源文件包含,但这时可能会有一个问题
	头文件会被重复包含
*/

#pragma once //解决头文件被重复包含

/*
	1.C头文件
	2.所有的变量的声明
	3.所有的函数的声明
	4.#deifne,类型typedef,结构体struct
*/

#include<stdio.h>
#include<windows.h>
extern int g_val;//必须带上,虽然不报错,但是你写成
                 //int g_val;你就不清楚这是声明还是定义了
extern void show();//可以不带extern,但建议带,养成好习惯

这时有人说了,为什么变量必须需要,而函数只是建议呢?
    因为函数的声明和定义是看函数是否有函数体
    void show();有;结束了,没有函数体,这个就一定声明

当我们再main.c的程序中引用test.h头文件时,这时g_val变量和show()函数的声明都已经在test.h声明了,我们不需要再声明就可以是用了,而且没有任何警告和错误。

修改后的main.c源码

#include"test.h"

int main()
{
	printf("%d\n", g_val);
	show();
	//这时g_val变量和show()函数的声明都已经在test.h声明了,
	//我们不需要再声明就可以是用了
	return 0;
}

运行结果:

 通过上面的多文件的学习我们可以知道:

        全局变量和函数都可以跨文件访问,但是在未来我们编写程序时,我们不想要全局变量和函数都可以跨文件访问,只想在本文件内部被访问,这是我们就需要使用static关键字。

stati修饰全局变量和函数

当我们再test.c程序中的int g_val = 10;和void show()前加上static修饰时

#include "test.h"

static int g_val = 10;

static void show()
{
	printf("hello world!\n");
}

再运行main.c程序时就产生链接性(LNK)报错,这样我们就达到了不想要全局变量和函数都可以跨文件访问,只想在本文件内部被访问的目的了。

 static修饰局部变量

#include <stdio.h>

void foo() {
    int count = 0;
    count++;
    printf("This is the %dth time I'm called.\n", count);
}

int main() {
    foo();
    foo();
    foo();
    return 0;
}

在上述代码中,我们定义了一个名为 `foo` 的函数,并在其中定义了一个局部变量 `count`。每次调用 `foo` 函数时,`count` 的值都会自增,并且在函数内部打印出当前函数被调用的次数。由于 `count` 是局部变量,它会在函数结束释放空间,导致count内容也没有了,因此以后每次调用 `foo` 函数时都不会记住上一次的值,每次进入函数都会重现创建变量count,为其开辟空间进行初始化。因此输出的结果会类似于:

This is the 1th time I'm called.
This is the 1th time I'm called.
This is the 1th time I'm called.

当我们用static修饰局部变量count时

#include <stdio.h>

void foo() {
    static int count = 0;
    count++;
    printf("This is the %dth time I'm called.\n", count);
}

int main() {
    foo();
    foo();
    foo();
    return 0;
}

每次调用 `foo` 函数时,`count` 的值都会自增,并且在函数内部打印出当前函数被调用的次数。由于 `count` 是静态变量,它只会在程序初次运行时被初始化,以后每次调用 `foo` 函数时都会记住上一次的值,因此输出的结果会类似于:

This is the 1th time I'm called.
This is the 2th time I'm called.
This is the 3th time I'm called.

我们再来看一段代码:

#include<stdio.h>

int* p = NULL;

void fun()
{
    static int b = 100;
    p = &b;
}

int main()
{
    fun();
    printf("%d\n", *p);//100
    return 0;
}

 我们可以发现,当我们进行程序调试的时候,当调试到printf函数的时候,我们发现b和&b已经是未声明的标识符了,说明此时变量已经出了它的作用域,从而可以证明static修饰的局部变量不会改变变量的作用域。再回到上面那个程序,调用`foo` 函数,虽然count变量每次出了作用域也不能访问它,但是编译器却记住了每一次count的值,再其作用域内打印count的值只有第一次进行初始化,后面一次是count++的值,但是当我们去掉static的时候,每次调用函数都会为count变量进行初始化,并没有记录count的值,说明static修饰的局部变量增长了局部变量的生命周期

static关键字总结

1. 全局变量:使用 `static` 关键字修饰变量时,它的作用域被限定在声明该变量的源文件内,不会被其他源文件所直接使用。此外,静态变量的生命周期和程序的执行周期相同,它只会在程序初次运行时被初始化,以后每次函数调用都会记住上一次的值,不会被销毁。

2. 静态函数: 使用 `static` 关键字定义函数时,该函数的作用域被限定在声明该函数的源文件内部,其它源文件无法直接访问该函数。这在一些小的项目中很有用,可以减少命名冲突和全局污染的问题。

3. 局部变量:使用 static 修饰的局部变量块会在程序启动时只被初始化一次,之后每次进入该代码块都会记住上一次执行的结果。

总的来说,`static` 关键字可以用于限制变量、函数的作用域和可见性,保证其只在需要的范围内被访问和使用。同时,静态变量的生命周期和作用域是静态的,能够方便地保存一些信息,减少全局变量带来的问题。

注意上面加粗的语言,不能直接访问,但是可以间接访问,我们可以使用嵌套的方式对外进行调用,所有并不是绝对的不能访问。这样的间接访问,使用者只会知道其实现的功能,并不知道实现方式,极大程度上维护了程序的安全,是一种程序的封装。这样别人无法修改我们的全局变量和函数,这样我们的程序就非常安全。

static项目维护,提供安全保证

#include "test.h"

static int g_val = 10;

static void show()
{
	printf("%d\n", g_val);
	printf("hello world!\n");
}

void show1()
{
	show();
    //当我们在test.c中声明该函数并且main.c中调用该函数就可以使用全局变量和函数了
}

如果我们也不想此函数被其他文件再使用,那咱们就加static。

几个问题

1.c语言要设置全局变量和函数可以跨文件使用的原因

        C语言要设置全局变量和函数可以跨文件使用,主要是为了方便程序员进行代码组织、管理和重用。具体原因如下:

1. 代码组织和管理方便:将不同功能的代码模块分别编写在不同的文件中,可以使得代码的组织和管理更加清晰和方便,便于程序员维护和管理代码。

2. 函数重用性提高:将函数定义在一个独立的文件中,可以使得程序员在不同的程序中多次调用相同的函数,从而提高了函数的重用性,避免了重复编写代码的麻烦。

3. 变量共享:全局变量可以在程序的不同部分之间共享,可以在函数之间传递数据,避免了在每个函数之间频繁地传递数据的麻烦。

4. 代码可读性提高:将不同功能的代码模块分别编写在不同的文件中,也有助于代码的可读性,使得程序员可以更加清晰地理解程序的结构和逻辑。

总之,C语言的全局变量和函数可以跨文件使用,为程序员提供了方便的代码组织、管理和重用方式,有助于提高程序的可维护性、可重用性和可读性。多个文件之间的函数调用可以通过函数声明和头文件实现,使得程序员可以将不同功能的代码模块分别编写在不同的文件中,方便代码的管理和维护。同时,这种跨文件的函数调用方式也提高了代码的可重用性,可以使得相同的函数可以在不同的程序中多次调用,降低了代码的重复编写和维护成本。

2.C程序地址空间是什么样的?

C程序的地址空间通常被划分为以下五个部分:

1. 文本段(Text Segment,也称代码段/只读代码区):存放程序的机器指令,是可执行的代码段。该段通常是只读的,并且是共享的,因为多个进程可以同时运行同一个程序,而它们所使用的指令流是相同的。在程序运行期间,文本段的内容通常是不变的。这个区域一般包括程序的指令、常量、字符串等数据。

2. 数据段(Data Segment,也称已初始化数据区/全局数据区):存放程序中已经初始化的全局变量和静态变量,例如int、float、double等类型的数据。这个区域的数据在程序的整个执行过程中都存在,并且可以被程序中的所有函数所访问。

3. BSS段(或未初始化数据段):存放程序中未初始化的全局变量和静态变量,例如未初始化的int、float、double等类型的数据。在程序运行之前,BSS段的内容被初始化为0或NULL。随着程序的执行过程,程序可以动态地在BSS段中分配内存。

4. 堆(Heap):存放程序运行期间动态分配的内存。堆的大小可以根据程序的需要进行扩展或缩小,不能保证堆的连续性。通常,程序员通过调用malloc、calloc、realloc等函数来使用堆内存。

5. 栈(Stack):存放函数调用时的局部变量、函数的参数、以及函数的调用和返回信息,这些数据的大小在编译时不能确定。栈的大小可以根据需要动态地增加或减少,但是栈内存的使用必须保证栈的连续性。

3.局部变量为什么具有临时性

        局部变量具有临时性是因为它们只在函数调用期间存在,当函数返回时,局部变量的内存空间就会被释放。这是因为局部变量在栈上分配内存,栈是一种具有后进先出(LIFO)特性的内存结构,每次函数调用时,系统会在栈上分配一段内存作为函数的临时存储空间,在函数返回时,系统会释放这段内存,以便让其他函数使用。

因此,局部变量的生命周期受限于函数的执行周期,当函数执行结束时,它所占用的内存空间都被释放了,局部变量也就不存在了。这种临时性使得局部变量只能在函数内部使用,对于其他函数来说是不可见的。

相比之下,全局变量和静态变量是具有永久性的,它们在程序启动时被分配内存,并在整个程序执行期间存在。因此,全局变量和静态变量可以在程序的任何位置进行访问和修改,而局部变量只能在函数内部使用。

总之,局部变量的临时性是由于它们只在函数调用期间存在。

4.全局变量为什么具有全局性

        全局变量具有全局性是因为它们在程序运行期间始终存在于内存中,并且可以在程序的任何地方被访问到。这是因为全局变量的存储位置是在程序的静态数据区或全局数据区中。这个区域在程序开始时就被分配出来,直到程序结束时才会被释放掉。

在 C 语言中,全局变量的定义通常放在函数外部,这会导致它们的作用域扩展到整个源代码文件。如果全局变量在某个文件中定义,但没有被声明为 static,那么该变量的作用域将扩展到整个程序中,即使在其他文件中也可以通过 extern 关键字来访问它,这就是所谓的“全局性”。

全局变量在编译时就已经被分配了内存空间,因此它们的地址在程序运行期间是固定的。这些全局变量存储在静态数据区或全局数据区,这个区域通常不可写,因此被称为“常量区”或“只读数据区”。全局变量的地址在程序整个运行期间都是固定的,可以在程序的任何地方被访问和修改。

总之,全局变量具有全局性是因为它们存储在地址空间的静态数据区或全局数据区中,并且在程序整个运行期间都存在于内存中。

5.为什么static修饰的局部变量生命周期会变长

在 C中,static 关键字可以用来改变变量的存储方式、作用域和生命周期。当 static 用来修饰局部变量时,它的作用是使得这个变量的生命周期变长,即在函数执行完之后,该变量的值仍然存在于内存中,没有被释放掉,直到程序结束时才会释放掉这个变量所占用的内存空间。这种特性使得 static 修饰的局部变量可以在函数调用之间共享信息,对于一些需要保持状态的变量,比如计数器、缓存等,可以使用 static 修饰。

在函数第一次被调用时,静态局部变量才被创建,之后每次调用函数时,它的值保持不变。因此,静态局部变量在内存中只能被创建一次,并且只被初始化一次,以后每次函数调用时,静态局部变量所占用的内存地址是相同的。这就是为什么 static 修饰的局部变量的生命周期会比普通局部变量的生命周期更长的原因。

需要注意的是,static 修饰的变量只能在定义它们的函数内部访问,对于其他函数来说是不可见的。另外,由于静态局部变量在内存中只被创建一次,所以它们的初始值只被赋值一次,如果没有显式的初始化语句,它们会被自动初始化为 0 或者 NULL。

6.static修饰的局部变量再地址空间会有什么变化吗

static 修饰的局部变量在地址空间上与普通局部变量存在差别。

普通局部变量通常存在于栈空间中,栈空间是一种后进先出的数据结构。每次函数调用时,系统会在栈空间中为该函数分配一段临时的内存空间,函数执行结束时,这段内存空间就会被释放。

而 static 修饰的局部变量则存在于全局数据区中,也称为静态数据区、静态存储区或者数据段。全局数据区是在程序运行期间一直存在的一块内存空间,由编译器在程序启动时自动分配,它的大小在程序运行期间不会发生改变。在程序运行期间,该内存空间中的值始终保持不变。因此,static 修饰的局部变量在地址空间上与普通局部变量存在差别。具体而言,在 x86 架构的计算机中,全局数据区会被分成两个部分:

1. 数据段(Data Segment):用于存储全局变量、静态变量以及常量字符串等。数据段的大小在编译时就已经确定。

2. BSS 段(Block Started by Symbol):用于存储未经初始化的全局变量、静态变量以及 BSS 段数组。BSS 段的大小在程序启动时会被设置为 0,并在程序运行时动态分配内存。

static 修饰的局部变量在存储上与全局变量类似,它们都存储在数据段或 BSS 段中,具有静态存储周期和全局作用域。而对于普通局部变量,在函数调用结束后,它们所占用的栈空间就会被释放掉,对应的地址空间也就不存在了。

基本数据类型

前面我们已经介绍了定义变量的本质是:在内存中开辟一块空间,用来保存数据。而定义一个变量,是需要类型的,这个是基本语法决定的,那么,类型决定了:变量开辟空间的大小。

最冤枉的关键字  -  sizeof

sizeof 是 C中的一个关键字,用于获取数据类型或变量在内存中所占用的字节数。sizeof 操作符返回值的类型是 size_t,这是一个无符号整数类型,大小足以容纳所查询对象的大小。

sizeof 操作符可以用于以下情况:

1. 获取数据类型的大小:使用 sizeof 可以查询数据类型的大小,例如 sizeof(int) 可以获取 int 类型在当前平台上所占用的字节数。

2. 获取变量的大小:使用 sizeof 可以查询变量在内存中所占用的字节数,例如 sizeof(a) 可以获取变量 a 在内存中所占用的字节数。

注意,sizeof 可以用于任何数据类型,包括基本数据类型和自定义数据类型,例如结构体和类。 在使用 sizeof 时,需要注意以下几点:

1. sizeof 返回值的类型是 size_t,需要在代码中使用正确的类型进行接收和处理。

2. 对于指针类型,sizeof 返回的是指针变量本身所占用的字节数,而不是指针所指向的对象所占用的字节数。如果要获取指针所指向的对象大小,可以使用 sizeof(*ptr),其中 ptr 是指向对象的指针。

3. 在使用 sizeof 获取数组大小时,需要注意数组中每个元素的大小,因为数组所占用的总字节数等于元素大小乘以数组长度。

综上所述,sizeof 是一个用于获取数据类型或变量在内存中所占用的字节数的关键字,可以帮助程序员更好地管理内存和设计数据结构。在使用时需要注意数据类型、指针、数组等特殊情况。

 sizeof关键字是求数据类型的大小,单位是字节

#include <stdio.h>
int main()
{
    printf("%d\n", sizeof(char));                    //1字节
    printf("%d\n", sizeof(short));                   //2字节
    printf("%d\n", sizeof(int));                       //4字节
    printf("%d\n", sizeof(long));                    //4字节
    printf("%d\n", sizeof(long long));            //8字节
    printf("%d\n", sizeof(float));                    //4字节
    printf("%d\n", sizeof(double));                //8字节
    printf("%d\n", sizeof(long double));        //8字节
    return 0;
}

接下来,我们来看一段代码

#include<stdio.h>
int main()
{
    //sizeof:确定一种类型对应在开辟空间时候的大小
    //判断那个代码能输出正确的结果
    int a = 10;
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof int);
    printf("%d\n", sizeof a);
    return 0;
}

        这段代码主要演示了C语言中`sizeof`关键字的使用。 `sizeof`可用于计算数据类型、变量、数组等的大小。在这段代码中,`sizeof(int)`、`sizeof(a)`和`sizeof a`分别求`int`类型和`a`变量所占的字节数,输出结果相同。 而`sizeof int`,在实际运行时会报错。因为`sizeof`后面必须要跟着一个表达式,而`int`不是完整的表达式。最终,这段代码会输出以下结果:

4

4

error: expected expression(应输入表达式)

4

一般我们写函数调用的时候,例如入求两数之和,当我们要使用的时候,就调用函数,形式‘Add(a,b)’,这个和上面的sizeof(a)很相似,但是我们千万不能把sizeof也当作函数,它只是个操作符,printf("%d\n", sizeof a);上面的这句代码也可以运行,没有带小括号(),而我们知道函数调用需要使用小括号()操作符,所以我们可以证明sizeof只是操作符,不是函数

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

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

相关文章

vue-cli版本号始终是2.9.6,且无法删除,安装更新无效的问题。

参考博客 目录 1.问题出现原因2.我的解决办法&#xff1a;删除原脚手架&删除原vuevue.cmd 1.问题出现原因 从各种博客我得知&#xff0c;这种问题出现在2处&#xff1a; 没有卸载原来的脚手架原来的vue和vue.cmd没删除干净 2.我的解决办法&#xff1a;删除原脚手架&…

[oeasy]python0135_命名惯用法_name_convention

命名惯用法 回忆上次内容 上次 了解了isidentifier的细节 关于 关键字关于 下划线 如何查询 变量所指向的地址&#xff1f; id 如何查询 已有的各种变量&#xff1f; locals 如果 用一个变量a的值 给另一个变量b 赋值是什么样的过程 呢&#xff1f;&#xff1f;&#x1f914;…

当,Kotlin Flow与Channel相逢

前言 之前的文章已经分析了Flow的相关原理与简单使用&#xff0c;Flow之所以用起来香&#xff0c;Flow便捷的操作符功不可没&#xff0c;而想要熟练使用更复杂的操作符&#xff0c;那么需要厘清Flow和Channel的关系。 本篇文章构成&#xff1a; 1. Flow与Channel 对比 1.1 Fl…

AVL树(C++实现)

文章目录 AVL树的概念AVL树结点定义AVL树的插入AVL树的旋转左单旋右单旋左右单旋右左双旋 AVL树的验证AVL树的性能AVL树及测试完整代码 AVL树的概念 二叉搜索树虽然可以缩短查找的效率,但如果数据有序或接近有序,那么二叉搜索树将退化为单支树,查找元素则相当于在顺序表中搜索…

从零手写Resnet50实战——利用 torch 识别出了虎猫和萨摩耶

大家好啊&#xff0c;我是董董灿。 自从前几天手写了一个慢速卷积之后&#xff08;从零手写Resnet50实战—手写龟速卷积&#xff09;&#xff0c;我便一口气将 Resnet50 中剩下的算法都写完了。 然后&#xff0c;暴力的&#xff0c;按照 Resnet50 的结构&#xff0c;将手写的…

【Flowable】Flowable基础表结构

1.表结构讲解 表结构创建文件&#xff1a;flowable-engine-6.3.0.jar!\org\flowable\db\create\flowable.mysql.create.engine.sql 工作流程的相关操作都是操作存储在对应的表结构中&#xff0c;为了能更好的弄清楚Flowable的实现原理和细节&#xff0c;我们有必要先弄清楚Fl…

Python边缘检测之prewitt, sobel, laplace算子

文章目录 滤波算子简介具体实现测试 滤波算子简介 ndimage中提供了卷积算法&#xff0c;并且建立在卷积之上&#xff0c;提供了三种边缘检测的滤波方案&#xff1a;prewitt, sobel以及laplace。 在convolve中列举了一个用于边缘检测的滤波算子&#xff0c;统一维度后&#xf…

es6 const的使用

1.const用来定义常量&#xff0c;赋值知乎不能再赋值&#xff0c;再次赋值会报错。 <script>//1.定义常量&#xff0c;赋值后不能再赋值&#xff0c;在赋值报错const count 1// count 2</script> ​ 2.const不能只声明不赋值&#xff0c;会报错。 <script>…

智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络)

智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络) 目录 智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络)预测效果基本介绍程序设计参考资料预测效果 基本介绍 MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法…

chatGPT衣食住行10种场景系列教程(01)chatGPT热点事件+开发利器

导读 时隔5个多月&#xff0c;chatGPT可谓是一日千里&#xff0c;越演越火&#xff0c;携带着AIGC行业一起飞了起来&#xff0c;那么在短短5个月当中有那些值得我们关注的事件&#xff1f;有那些好玩的场景&#xff1f;以及有那些chatGPT好用的工具&#xff1f;本文都将一一告…

大数据时代必备技能,学好数据可视化

互联网时代&#xff0c;都在强调数据分析的重要性&#xff0c;但是干巴巴的数据没人爱看&#xff0c;老板们对“简单直观地看数据”的需求愈发强烈。随着大数据建设的如火如荼&#xff0c;别讲底层技术和算法牛逼&#xff0c;最终的效率提升、业绩提升要通过数据展示出来&#…

vba:消息框基础,msgbox

常量常量值说明vbOKOnly0只显示“确定”按钮&#xff08;缺省值&#xff09;VbOKCancel1显示“确定”和“取消”按钮VbAbortRetryIgnore2显示“终止”、“重试”和“忽略” 按钮VbYesNoCancel3显示“是”、“否”和“取消”按钮VbYesNo4显示“是”和“否”按钮VbRetryCancel5显…

Python爬虫实战——获取电影影评

Python爬虫实战——获取电影影评 前言第三方库的安装示例代码效果演示结尾 前言 使用Python爬取指定电影的影评&#xff0c; 注意&#xff1a;本文仅用于学习交流&#xff0c;禁止用于盈利或侵权行为。 操作系统&#xff1a;windows10 家庭版 开发环境&#xff1a;Pycharm Co…

Linux 服务简单优化

硬件优化 处理器&#xff1a;核心数、主频、制程工艺、线程数、缓存等 核心数&#xff1a;1、2、4、6、8、12、24、32等 主频&#xff1a;2.0GHz、2.3GHz等等 制程工艺&#xff1a;22nm、14nm、10nm等等 线程数&#xff1a;1、2 缓存&#xff1a;L1、L2、L3 建议&#xff1a;尽…

OpenHarmony 3.2 Release特性更新简析

1.ArkUI 组件能力增强 支持XComponent控件&#xff0c;可用于EGL/OpenGL ES和媒体数据写入&#xff0c;并在XComponent组件显示&#xff1b;通过XComponent组件&#xff0c;配合NDK能力&#xff0c;构建C/ArkTS混合开发能力&#xff0c;支持游戏、媒体应用开发支持AbilityCom…

前端学习:HTML内联框架

目录 一、HTML Iframe 二、添加iframe的语法 三、Iframe设置高度和宽度 ​编辑 四、Iframe删除边框 五、使用iframe作为链接的目标 六、补充 一、HTML Iframe iframe用于在网页内显示网页。 二、添加iframe的语法 <iframe src"URL"></iframe> 提示…

“计数”排序

目录 一、什么是计数排序&#xff1f;二、如何实现计数排序&#xff1f;三、适用场景四、时间复杂度和空间复杂度 一、什么是计数排序&#xff1f; 计数排序&#xff0c;是通过统计每一个数字出现的次数&#xff0c;并把它映射到与它自己本身数值相同的下标处&#xff0c;再遍…

HoloLens2场景理解,识别平面信息

因为可用的资料比较少,就记录下吧,大家也可以少走弯路,节省时间。 场景理解,通俗的讲,可以识别空间当中的墙面、地板、天花板、平台等. 场景理解&#xff08;Scene Understanding&#xff09;是指 HoloLens2 通过深度传感器、摄像头和计算机视觉算法等技术&#xff0c;能够对…

Centos安装Nvidia驱动解决内核版本不匹配问题

Centos安装Nvidia驱动解决内核版本不匹配问题 问题分析尝试解决 写程序三分钟&#xff0c;配环境三小时&#xff0c;尤其是在一台全新机器/重装系统后。。。 已经解决的&#xff1a; 禁用nouveau驱动并重启电脑&#xff08;参考这篇博客&#xff09;缺少cc&#xff0c;手动yum…