C语言---操作符详解

news2024/11/15 15:40:00

1、操作符分类

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号操作符

下标引用、函数调用和结构成员。

2、算数操作符

+      -       *        /        %
    
    
    
//  7 / 2    ----->3
//  7 % 2    ----->1
    
//那如果想要打印出小数呢?只需要两端有一个浮点数就会执行浮点数得出发
#include <stdio.h>
int main()
{
	float a = 7 / 2.0;
	printf("%.1f\n",a);          //.1就是保留小数点后一位
	return 0;
}

3、移位操作符(二进制)

<< 左移位符          就是左边丢弃,右边补0。

>> 右移位符
    
注:移位操作符的操作数只能是整数

移位操作符,移动的是二进制位。

警告:对于移位运算符,不要移动负位数,这个是标准定义的。

3.1、左移位

3.1.1、原码、反码、补码介绍

整数的二进制表示有3种:

  • 原码
  • 反码
  • 补码

正的整数的原码、反码、补码相同。

负的整数的原码、反码、补码是要计算的。

1、比如7的原码、反码、补码:

因为7是正值所以,原码 = 反码 = 补码

7是int类型的,占4个字节,一个字节=8bit,所以:

原码 = __0__0000000000000000000000000000111

注意:最高位(就是最左边的哪一位)0代表是正数,1代表是负数。

2、-7的原码、反码、补码

  • 原码:10000000000000000000000000000111
  • 反码:11111111111111111111111111111000(按照原码的最高位不变,其它的取反)
  • 补码:11111111111111111111111111111001(反码+1=补码)

整数在内存中存储的是补码。

3.1.2、求a=7,a<<1的值

那么接下来言归正传,既然移位操作符,移动的是二进制,那移动的肯定是存储在内存中的补码。

比如:7,补码是:__0__0000000000000000000000000000111。

那如果进行b= 7 <<1;向左移位,就是左边丢弃,右边补0。

那得到的补码结果就是: 00000000000000000000000000001110

那么此时补码的结果转为十进制就是:8+4+2+0=14

看代码效果:

#include <stdio.h>
int main()
{
	int a = 7;
	int b = a << 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

输出:

在这里插入图片描述

可见a左移一位,a本身没有变化。

3.1.3、求a=-7,a<<1的值

-7的补码:11111111111111111111111111111001,那根据左移位:左边丢弃,右边补0的原则来推算,可以得到新的补码为:11111111111111111111111111110010。那这时注意,如果想要得到a<<1的值,需要-7的原码,然后转为十进制即可。

所以现在需要反推,新的补码:11111111111111111111111111110010,那么补码-1就是反码,那求出反码(最高位不取反)为:11111111111111111111111111110001,然后在取反得到原码:10000000000000000000000000001110

这个原码转为十进制是:8+4+2+0=14,又因为是a=-7,所以a<<1=-14。

代码验证:

#include <stdio.h>
int main()
{
	int a = -7;
	int b = a << 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

输出:

在这里插入图片描述

3.1.4、得出左移位的结论

a=7,那a<<1=14

a=-7,那a<<1=-14

所以左移位有原数*2的效果。

3.2、右移操作符

右移操作符分为两类:

  • 算术移位:右边丢弃、左边补原符号位。
  • 逻辑移位:右边丢弃,左边补0。

具体的算数移位和逻辑移位是取决于编译器的。UP🐖见过的都是算数移位。

3.2.1、求a=7,a>>1的值

算术移位:右边丢弃、左边补原符号位。

补原符号位就是a<<1,a如果是正数,就补0,a如果是负数就补1。

比如:7的补码:__0__0000000000000000000000000000111,按照:右边丢弃,左边补原符号位。那得到的新补码就是:__0__000000000000000000000000000011,所以此结果是:2+1=3。

代码验证:

#include <stdio.h>
int main()
{
	int a = 7;
	int b = a >> 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

输出:

在这里插入图片描述

3.2.2、求a=-7,a<<1的值

7的补码:11111111111111111111111111111001,那根据:右边丢弃,左边补原符号位。那得到的新补码就是:1111111111111111111111111111100(算数移位)或者0111111111111111111111111111100(逻辑移位),那具体是那个移位呢?

VS编译器是算数移位。

分析:-7的新补码:1111111111111111111111111111100,新补码-1=反码=1111111111111111111111111111011,然后取反(最高位不取反)然后得到原码:1000000000000000000000000000100

然后转为十进制结果为:-4。

代码验证:

#include <stdio.h>
int main()
{
	int a = -7;
	int b = a >> 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

输出:

在这里插入图片描述

4、位操作符

位操作符有:

  • & -> 按(2进制)位与
  • | -> 按(2进制)位或
  • ^ -> 按(2进制)位异或

4.1、&按位与

下面先来看那段代码:

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	printf("c=%d\n", c);
	return 0;
}

输出:

在这里插入图片描述

分析:既然内存中放的是补码,所以我们将3和-5的补码写出来:

//3的原码:__0__0000000000000000000000000000011,因为正数的原码=反码=补码。所以:

//3的补码:__0__0000000000000000000000000000011

//-5的原码:__1__0000000000000000000000000000101,取反:

//-5的反码:__1__1111111111111111111111111111010,根据:反码+1=补码,所以:

//-5的补码:__1__1111111111111111111111111111011

那么现在将3和-5的补码进行按位与。

按位与的规则:只要有0,按位与的结果就是0(两个0按位与也是0),两个全部是1,按位与的结果就是1。

3的补码:__0__0000000000000000000000000000011

-5的补码:__1__1111111111111111111111111111011

按位与后的补码:__0__0000000000000000000000000000011

由于按位与后的补码符号位是0,是正数,正数的补码=反码=原码,所以原码结果为:2+1=3,所以3 & 5 = 3,所以上述代码正确。

4.2、| 按位或

先来看段代码:

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a | b;
	printf("c=%d\n", c);
	return 0;
}

输出:

在这里插入图片描述

按位或的规则:两个数只有1结果为1,两个数全部是0,结果为0。

下面还是需要补码。

分析:

3的补码: __0__0000000000000000000000000000011

-5的补码: __1__1111111111111111111111111111011

得到按位或的补码:__1__1111111111111111111111111111011

由于得到按位或的补码符号位是1,为负数,所以需要-1为反码,然后在取反为原码,然后转为十进制,取值。

按位或的补码-1=反码:__1__1111111111111111111111111111010,

然后反码取反=原码:10000000000000000000000000000101,转化为是十进制为5,又因为符号位为1,所以为负数,所以最终结果为-5。

4.3、^ 按位异或

先来看段代码:

#include <stdio.h>
int main()
{
	int a = 3;
	int b = -5;
	int c = a ^ b;
	printf("c=%d\n", c);
	return 0;
}

输出:

在这里插入图片描述

按位异或的规则:相同为0(两个都是0结果为0,两个都是1结果为1),相异为1

分析:

3的补码: __0__0000000000000000000000000000011

-5的补码: __1__1111111111111111111111111111011

按位异或后的补码:__1__1111111111111111111111111111000

补码-1=反码:__1__1111111111111111111111111110111

反码取反=原码:__1__0000000000000000000000000001000

转为十进制为8,因为符号位为1,所以结果为负,所以结果是-8。

4.3.1、记着结论:

  • a ^ a = 0
  • 0 ^ a = a
  • a ^ a ^ b = a ^ b ^ a(说明按位异或支持交换律)。

4.3.2、不创建临时变量,交换两个整数的值

#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前a=%d b=%d\n", a, b);
	a = a ^ b;         //a=3^5
	b = a ^ b;         //b=3^5^5  ---->  b=3
	a = a ^ b;         //a=3^5^3  ---->  a=5
	printf("交换前a=%d b=%d\n", a, b);
	return 0;
}

输出:

在这里插入图片描述

5、赋值操作符

int weight = 100;         //初始化
     
weight = 200;             //赋值

a = x = y+1;

6、单目操作符

!                     逻辑反操作
-                     负值
+                     正值
&                     取地址
sizeof                操作数的类型长度(以字节为单位)
~                     对一个数的二进制按位取反
--                    前置--、后置--
++                    前置++、后置++
*                     间接访问操作符(解引用操作符)
(类型)                 强制类型转换
    
    

在C语言中0代表假,非0代表为真

6.1、!的介绍

#include <stdio.h>
int main()
{
	int flag = 0;           //flag初始化为0,所以flag此时为假
	if (!flag)              //那既然flag为假,那么!flag就为真
		printf("现在为真");
	return 0;
}

6.2、sizeof的使用介绍

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", sizeof(a));        //4
	printf("%d\n", sizeof(int));      //4
	printf("%d\n", sizeof a);         //因为size是个操作符,所以不带()也可以使用   输出:4

	return 0;
}

当然sizeof也可以统计数组的类型大小

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	printf("%d\n", sizeof(arr));            //40
	printf("%d\n", sizeof(arr[0]));        //4,
	printf("%d\n", sizeof(arr) / sizeof(arr[0]));       //计算数组中元素的个数的方法
	return 0;
}

6.3、–、++的使用

这里只说明一个++即可,–的使用同理

1、先说后置++,eg:a++,后置++遵循一个原则:先使用,后++

#include <stdio.h>
int main()
{
	int a = 10;
	int b = a++;           //先使用,后++,也就是先 int b = a,然后在a = a+1
	printf("%d\n", b);
	printf("%d\n", a);
	return 0;
}

输出:
    10
    11

2、前置++,eg:++a。前置++遵循一个原则:先++,后使用

#include <stdio.h>
int main()
{
	int a = 10;
	int b = ++a;           //先++,后使用,也就是先 a = a+1,然后在int b = a
	printf("%d\n", b);
	printf("%d\n", a);
	return 0;
}

输出:
    11
    11

常规的操作就不说了,下面来看这个代码:

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", a--); //a--是个表达式,先使用,后--,先使用那表达式结果就为10.
	printf("%d\n", a);  //后--,a=9
	return 0;
}

输出:

在这里插入图片描述

还有这个代码也是一样的道理:

#include <stdio.h>
int main()
{
	int a = 10;
	test(a--);         //这里传参的值也是10
	return 0;
}

在C语言中,for循环中i++,++i效果都是一样的。但在C++中就不一样了。

6.4、强制类型转换

#include <stdio.h>
int main()
{
	int a = (int)3.14;
	printf("%d\n", a);
	return 0;
}

输出:
    3

6.5、~ 二进制按位取反

先来看段代码:

#include <stdio.h>
int main()
{
	int a = 3;
	printf("%d\n", ~a);
	return 0;
}

输出:

在这里插入图片描述

~是按二进制取反,那肯定是对一个数的补码进行取反。

3是个整数,所以:原码=反码=补码:__0__0000000000000000000000000000011

那么~a就是对补码取反得到新补码:__1__1111111111111111111111111111100

注意:这里取反之后,符号位就变成1了,也就意味着是负数了,

然后在求~a的值,新补码-1=反码:__1__1111111111111111111111111111011,

反码取反=原码:__1__000000000000000000000000000100

转为十进制就是4,又因为符号位位1,所以最终结果为-4。

6.6、* 解引用操作符

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	*p = 20;        //*对p解引用,通过p里面存储的地址,找到它所指向的对象。
	printf("%d\n", a);
	return 0; 
}

7、关系操作符

>       >=      <      <=     !=

7.1、关于字符串比较

#include <stdio.h>
int main()
{
	if ("abc" == "abcdef") //这样比较不是字符串内容,而是字符串的首字符地址。
	{
		;
	}
	return 0; 
}

//字符串比较内容需要使用库函数:strcmp()

8、逻辑操作符

&&             逻辑与(并且)

||             逻辑或(或者)

8.1、这里有个重要的规则,如下:

如果:

  • a && b,如果a为假,则b不在执行。
  • a || b,如果a为真,则b也不在执行。

这个用于判断真假。a && b为真结果为1,a && b为假结果为0。如下:

#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5; 
	int c = a && b;           //c=1,1为真
	printf("%d\n", c);
	return 0; 
}

输出:

在这里插入图片描述

8.2、一道360面试题

如果:表达式1 && 表达式2,如果表达式1 为假,那么表达式2无论为真还是为假,表达式2就不会在算了。

如下代码:

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0; 
}

输出:

在这里插入图片描述

分析:因为a=0,a++之后,先使用,后++,所以a++表达式的结果为0,然后a后++所以最终a的值为1,既然a++表达式结果为0,所以&&前面的为假,所以后面的++b就不再运行了,所以b的值不变,b=2。由于a++为0,那么在第二个&&之前都是假,因此后面的d++也不在执行,所以d的值也没有发生改变,d=4,所以最终结果为1 2 3 4。(c=3从头就每改变)。

8.2.2、题型改编(1),提问:如果修改为a=1?

#include <stdio.h>
int main()
{
	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0; 
}

输出:

在这里插入图片描述

8.2.3、题型改编(2):吧&&变为||,结果为?

#include <stdio.h>
int main()
{
	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
	printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
	return 0; 
}

输出:

在这里插入图片描述

分析:由于a || b,a为真在,则b在不执行。a++这个表达式的结果为1,为真,然后后++,所以a=2,因为 a++这个表达式的结果为1所以第一个||后面的++b,不在执行,所以b=2。所以整个a++ || ++b为真,所以d++不在执行,所以d=4。最终结果为:2 2 3 4。

9、条件操作符

exp1?exp2:exp3
    
exp1 ? exp2 : exp3
 真     算     不算      那么整个表达式的结果就是exp2表达式的结果
 假    不算     算       那么整个表达式的结果就是exp3表达式的结果

代码示例:

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int r = a > b ? a : b;      //比较最大值
	printf("%d\n", r);
	return 0;
}

输出:
    20

在这里插入图片描述

10、逗号表达式

exp1,exp2,exp3,...expN

逗号表达式就是用逗号隔开的一串表达式。

逗号表达式的特点是:从左向右依次计算,整个表达式的结果是最后一个表达式的结果。

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 0;
	int d =(c = a - 2, a = b + c, c - 3);    //最后一个表达式c-3=5,所以最终输出结果5
	printf("%d\n", d);
	return 0;
}

输出:
    5

11、下标引用、函数调用和结构体调用

11.1、下标引用

arr[9],[]是操作符,arr 和 9是操作数。也就是说[]它的两个操作数是arr 和 9。

其实在写数组引用时,我们即可以这样写:arr[7],又可以这样写7[arr]。所以这就更说明了[]是个操作符。

其实arr[7]就是 *(arr+7)的解引用:

其实arr[7] —> *(arr+7)—> *(7+arr)—>7[arr]。

arr是数组首元素地址

arr+7就是跳过7个元素,指向第8个元素。

*(arr+7)就是第八个元素。

11.2、函数调用操作符—>()

Add(a,b):

  • ()是操作符
  • 操作数:Add,a,b。

11.3、结构体调用—> . ->

代码如下:

#include <stdio.h>

struct Stu
{
	char name [20];
	int age;
	char sex[5];
	char id[15];
};

void print(struct Stu* ps)
{
    //形式:结构体对象.结构体成员变量
	printf("%s %d %s %d\n", (*ps).name, (*ps).age, (*ps).sex, (*ps->id));
    printf("%s %d %s %d\n", ps->name, ps->age, ps->sex, ps->id);
    //形式:结构体指针->结构体成员
	//这两者所产生的效果一样。
}

int main()
{
	struct Stu S = 
	{
		"zhangsan",17,"nan","123456789"
	};
	print(&S);
	return 0;
}

就类比前面说到的指针变量那一节,道理一样。

11.4、关于结构体的简单总结

当使用此结构体时:有两种方法,这两种方法是等效的

  • 结构体对象.结构体成员变量,eg:(*ps).name
  • 结构体指针->结构体成员,eg:ps->name

ps->name等价于(*ps).name。

12、表达式求值

表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其它类型。

12.1、隐式类型转换

所谓的隐式类型转换,就是偷偷的类型转换,我们并不会感知到这个转换的动作,就已经转换完毕了。

注意:上面我们说了一句话:有些表达式的操作数在求值的过程中可能需要转换为其它类型。

怎么理解这句话呢?

这里引入一个概念:整型提升:

C的整型算术运算总是至少以缺省(默认)整型类型的精度进行的。

为了获得这个精度,表达式中的字符短整型操作数在使用之前被转换为普通整型。这种转换为__整型提升。__

整型提升的意义:

表达式的整型运算要在CPU的相应运算器内执行,CPU内整形运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接先相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转为int或unsigned int,然后在送入CPU中去执行运算。

大致意思如下,后面会详细分析过程。

//实例1
char a b c;
...
a = b + c;

在运算中,b和c的值被提升为普通整形,然后再执行加法运算。

加法运算完成之后,结果将被截断,然后存储在a中。

那既然知道了什么是整型提升。那我们如何进行整体提升呢?

整型提升是按照变量的数据类型的符号位来提升的。

//负数的整型提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
11111111
因为char为有符号的char,(有符号的char可以理解为是char类型的整数变量具有正负)
所以整型提升的时候,高位补充符号位,即为1。
所以提升后的结果是:11111111111111111111111111111111
    

//正数的整型提升
char c2 = 1;
变量c1的二进制位(补码)中只有8个比特位:
00000001
因为char为有符号的char,(有符号的char可以理解为是char类型的整数变量具有正负)
所以整型提升的时候,高位补充符号位,即为0。
所以提升后的结果是:00000000000000000000000000000001

详解一下这个负数整型提升,char c1 = -1;首先c1是char类型的,应该先整型提升,整型int是4个字节,1字节=8bit,所以4个字节=32bit,所以整型提升后的原码是:1000000000000000000000001,之后取反得到反码:11111111111111111111111111111110,之后+1,得到补码:11111111111111111111111111111111。

然后截断:11111111。

举个例子,比如:

#include <stdio.h>
int main()
{
	char a = 5;
	char b = 126;
	char c = a + b;
	printf("%d\n", c);
	return 0; 
}

输出:

在这里插入图片描述

思考一下:为什么这里的结果是-125呢?其实这就和整型提升有关!!!

分析:

首先正常的5的int类型的十进制补码为:00000000000000000000000000000101,但由于5现在是char类型的,所以,我们应该截断char是一个字节=8bit,所以直接后8位:__0__0000101。注意:这的最左边的一位仍是符号位,0代表正数,1代表负数。这里5是正数,所以为:__0__0000101。

同理,正常的126的int类型的十进制补码为:00000000000000000000000001111110,然后截断为:__0__1111110。

然后此时程序来到:char c = a + b; 这里我们可以发现:a+b,都是char类型的数据,是达不到int类型的,所以需要整型提升。

那就按照上面说到的规则进行整型提升:char类型的需要提升到int类型的,且char是有符号char,需要补24个bit,这补的24个bit,是补0还是补1呢?这需要看符号位。比如:char类型5的补码为:__0__0000101,符号位是0,所以前面的24bit位全部补0,所以整型提升后就是:__0__0000000000000000000000000000101。

(如果是无符号char,就不用考虑了,直接补0即可。)

同理:char类型的126的补码为:__0__1111110,整型提升后就为:__0__0000000000000000000000001111110。

好了,至此为止,整型提升结束,

现在使用它们开始运算:

  • __0__0000000000000000000000000000101 —> 5
  • __0__0000000000000000000000001111110 —> 126
  • __0__0000000000000000000000010000011 —> 相加的到后的结果

同理上面相加得到的结果是int类型的c的大小,但是现在c是char类型的,所以需要再次截断,直接后8bit位:得到:

  • 10000011 —>得到char类型的c,

然后走到打印printf("%d\n", c);这一步,由于是以%d的形式打印,所以c还需要整型提升,由于c的符号位是1,所以c、整型提升后的结果为:__1__1111111111111111111111110000011。但是这是还不能出结果,因为这里存储的只是补码,由于符号位是1,为负数。所以我们需要 补码-1=反码:__1__1111111111111111111111110000010,然后在取反=原码:1000000000000000000000001111101,最后在转为十进制,值为:125,又因为符号位是1,所以是负数,最终结果就是:-125。

这就是一个非int类型的数据,运算过程。

12.2、算术转换

ok。上面我们我们介绍了,小于整型类型(int)的数据在进行运算时,需要进行整形提升。那我们也许会问了,那要是数据类型超过了整型呢?那如何工作呢?这个时候就需要提到算数转换了。

算数转换针对的是整型及整形以上的类型。

算术转换:如果某个操作符的各个操作数属于不同类型,那么除非其中一个操作数转换化另一个操作数的类型,否则操作就无法进行,下面的层次体系称为__寻常算数转换。__

什么意思呢?简单来说就是:如果是两个不同类型的数据进行运算,其中一个类型要转换为另一个类型,比如:long 和int的数据进行运算,需要int类型的转为long类型,才能运算。

而究竟是int转换未long,还是long转换为int呢?这里有个规则:由低转高。也就是说long和int在一起,需要int转换为long类型的。

long double

double
    
long int
    
unsigned int     int   //这里unsigned int的范围高,所以进行算数转换需要将int转为unsigned int。

12.3、操作符的属性

复杂表达式的求值有三个影响的因素。

  • 操作符的优先级
  • 操作符的结合性
  • 是否控制求值顺序

两个相邻的操作符先执行那个?取决于它们的优先级,如果两者的优先级相同,取决于他们的结合性。

比如:

#include <stdio.h>
int main()
{
	2 + 3 * 4 + 5;
	return 0; 
}

比如:2+3*4+5,肯定是*优先级高,所以先算乘法,然后算加法,但是有两个加法,这时候优先级一样就需要看符号的结合性。加法是从左向右的,所以先算2+…,再算+5…。

但是就算确定了优先级,结合性,依然在运算中会出现问题,我们要做的就是吧自己的代码书写简单,不要太复杂。

总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。

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

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

相关文章

Java程序设计入门教程--类的创建过程

构造方法 在Java的每个类中都有一种特殊的成员方法&#xff0c;它的方法名和类名是一致的。在创建对象时&#xff0c;调用这种特殊方法对成员变量进行初始化&#xff0c;这种方法称为构造方法。 注意 创建构造方法与创建成员方法的格式相同&#xff0c;但要注意以下几点&#…

3GPP R16 HST

3GPP R16高铁场景为了能够支持最高3.6GHz载波频率以及最高500km/h的速度&#xff0c;提出了增强RRM要求和终端解调能力要求。 在增强RRM要求的维度&#xff0c;对intra-RAT和inter-RAT测量提出了新的要求。其中&#xff0c;intra-RAT测量包括NR小区重选要求、NR小区识别要求、波…

大数据:hadoop spark,spark特点,功能,架构,模块,角色

大数据&#xff1a;hadoop spark 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sq…

把玩数据在内存中的存储

前言&#xff1a;时光如梭&#x1f4a6;&#xff0c;今天到了C语言进阶啦&#x1f60e;&#xff0c;基础知识我们已经有了初步认识&#xff0c; 是时候该拔高拔高自己了&#x1f63c;。 目标&#xff1a;掌握浮点数在内存的存储&#xff0c;整形在内存的存储。 鸡汤&#xff1a…

arcgis for javascript api4.26 本地tomcat部署,以及解决跨域访问问题

一、配置java_jdk以及tomcat arcgis for javascript api 部署到本地服务器&#xff0c;可以是iis&#xff0c;也可以是tomcat,我这里是部署到tomcat,所以就介绍一下tomcat上部署的步骤。 如果电脑上有本地服务器的&#xff0c;可以跳过这一章&#xff0c;直接从第二章开始看 下…

1绪论_1.1数据结构的基本概念+1.2算法和算法评价

1.1.1基本概念和术语 数据 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 数据元素 数据元素是数据的基本单位&#xff0c;通常作为一个整体进行考虑和处理。一个数…

探索iOS自定义ijkplayer画中画播放

iOS提供AVPictureInPictureController用于画中画播放控制&#xff0c;但是只能绑定AVPlayer使用&#xff0c;对于开发者来说挺头痛的。在iOS 15.0后呼之欲出&#xff0c;支持SampleBufferDisplayLayer自定义数据源显示图层&#xff0c;意味着我们可以自定义第三方播放器实现画中…

内网安全:代理技术详解

目录 代理技术实验所用网络拓扑图及说明 代理技术 SOCK协议 使用代理技术的原因 正向代理与反向代理 实战一&#xff1a;MSF代理通讯 实验原理说明 一. Meterpreter建立路由 二. MSF建立节点 三. 建立代理到MSF上 实战二&#xff1a;CS代理通讯 实验原理说明 一. …

OpenGl之摄像机

文章目录 摄像机/观察空间摄像机位置摄像机方向右轴上轴 Look At自由移动移动速度鼠标输入缩放摄像机源码 OpenGL本身没有摄像机(Camera)的概念&#xff0c;但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机&#xff0c;产生一种我们在移动的感觉&#xff…

并发专栏-队列同步器 AQS 以及 Reentrantlock 应用

队列同步器 AQS 以及 Reentrantlock 应用 Java 中的大部分同步类都是基于AbstractQueuedSynchronizer&#xff08;简称为AQS&#xff09;实现的。 ReentrantLock、ReentrantReadWriteLock、Semaphore(信号量)、CountDownLatch、公平锁、非公平锁、 ThreadPoolExecutor 都和 AQS…

《C和指针》读书笔记(第九章 字符串、字符和字节)

目录 0 简介1 字符串基础2 字符串长度3 不受限制的字符串函数3.1 复制字符串3.2 连接字符串3.3 函数的返回值3.4 字符串比较 4 长度受限的字符串函数5 字符串查找基础5.1 查找一个字符串5.2 查找任何几个字符5.3 查找一个子串 6 高级字符串查找6.1 查找一个字符串前缀6.2 查找标…

饿补基础_1 |进位制、R进制之间转换及十进制编码

目录 数值数据的表示一.进位计数制理解1.你需要了解的概念2. 晦涩难懂的官方定义3 一看就会的例子4 值得收藏的进制对照表(二、八、十、十六进制)5 计算机为什么主要使用二进制 二.不同数制之间的转换1. 为什么会出现进制转换2. 各数制转十进制3. 十进制转二进制4. 二进制与八进…

java企业级信息系统开发学习笔记12 基于配置文件整合SSM框架实现用户登录

文章目录 一、学习目标&#xff08;一&#xff09;采用MVC架构 二、基于XML配置方式整合SSM框架实现用户登录&#xff08;一&#xff09;创建表&#xff08;二&#xff09;创建项目&#xff08;三&#xff09;添加相关依赖&#xff08;四&#xff09;创建日志属性文件&#xff…

leetcode51. N 皇后 (java)

leetcode 51 N 皇后 leetcode 51 N 皇后题目描述解题思路 代码演示leetcode52 N 皇后II leetcode 51 N 皇后 原题链接: https://leetcode.cn/problems/n-queens/ 题目描述 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研…

2023 华为 Datacom-HCIE 真题题库 07/12--含解析

多项选择题 1.[试题编号&#xff1a;190187] &#xff08;多选题&#xff09;如图所示的拓扑采用了VXLAN分布式网关&#xff0c;SW1上的VBDIF10配置了&#xff1a;arp-proxy local enable命令&#xff0c;则以下描述中正确的有哪些项&#xff1f; A、SW1收到PC1发往PC2的报文&…

【PHP】ThinkPhp6期末速通

目录 一、安装Composer二、设置Composer下载源三、Composer下载&#xff0c;安装TinkPHP6四、安装成功后 目录结构五、运行 ThinkPHP6 起步一、MVC二、单应用模式访问调试 三、安装视图四、模板渲染默认访问指定访问 五、模板变量默认赋值助手函数&#xff08;若不使用默认赋值…

K8s之Deployment控制器入门到深入详解

文章目录 一、Deployment 高级控制器理论1、Deployment控制器介绍2、Deployment工作原理 二、Deployment YAML编写及参数解释1、整体Deployment YAML资源清单内容&#xff1a;2、核心参数解释&#xff1a;3、Deployment更新策略&#xff1a;4、Deployment更新策略百分比方式计算…

内网穿透技术

文章目录 前言1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 转载自内…

测试必会 | 通过容器化 Python Web 应用掌握 Docker 容器核心技能

【摘要】 当多个窗口同时 attach 到同一个容器时&#xff0c;所有的窗口都会同步的显示&#xff0c;假如其中的一个窗口发生阻塞时&#xff0c;其它的窗口也会阻塞。attach 必须是登陆到一个已经运行的容器里&#xff0c;如果从这个容器中 exit 退出的话&#xff0c;会导致容器…

HNU-操作系统OS-实验Lab8

OS_Lab8_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 实验目的 通过完成本次实验,希望能达到以下目标 了解基本的文件系统系统调用的实现方法;了解一个基于索引节点组织方式的Simple FS文件系统的设计与实现;了解文件系统抽…