广东网站建设电话咨询,手机网站微信登录,中国数控机床网,做风投要关注哪些网站移位操作符 左移操作符 右移操作符 左移操作符 移位规则#xff1a; 左边抛弃、右边补0 右移操作符 移位规则#xff1a; 首先右移运算分两种#xff1a; 1.逻辑移位 左边用0填充#xff0c;右边丢弃 2.算术移位 左边用原该值的符号位填充#xff0c;…移位操作符 左移操作符 右移操作符 左移操作符 移位规则 左边抛弃、右边补0 右移操作符 移位规则 首先右移运算分两种 1.逻辑移位 左边用0填充右边丢弃 2.算术移位 左边用原该值的符号位填充右边丢弃 警告⚠ 对于移位运算符不要移动负数位这个是标准未定义的。例如
int num 10;
num-1;//errorsizeof 和数组
#include stdio.h
void test1(int arr[])
{printf(%d\n, sizeof(arr));//(2)
}
void test2(char ch[])
{printf(%d\n, sizeof(ch));//(4)
}
int main()
{int arr[10] { 0 };char ch[10] { 0 };printf(%d\n, sizeof(arr));//(1)printf(%d\n, sizeof(ch));//(3)test1(arr);test2(ch);return 0;
}问 1、2两个地方分别输出多少 3、4两个地方分别输出多少
答
(1) 输出为40(2) 输出为8(3) 输出为10(4) 输出为8
这些输出结果的原因如下所述
在 main 函数中sizeof(arr) 表示整型数组 arr 的大小即 10 个整型元素每个整型占据 4 个字节32 位系统下。因此sizeof(arr) 的结果为 10 * 4 40 字节。
在 main 函数中sizeof(ch) 表示字符型数组 ch 的大小即 10 个字符元素每个字符占据 1 个字节。因此sizeof(ch) 的结果为 10 字节。
在 test1 函数中arr 参数虽然声明为整型数组但在函数参数中数组会被转换为指针因此 sizeof(arr) 实际上返回的是指针的大小而不是整型数组的大小。在这里指针的大小是 8 字节64 位系统下。
在 test2 函数中同样地ch 参数虽然声明为字符型数组但在函数参数中数组也会被转换为指针因此 sizeof(ch) 返回的是指针的大小而不是字符型数组的大小。在这里指针的大小是 8 字节64 位系统下。
区分逻辑与或和按位与或
12-----0
12----1
1|2-----3
1||2----112 ----- 0 这里使用的是按位与运算符对应二进制的每一位进行与操作。1 的二进制表示为 012 的二进制表示为 10。按位与操作后得到的结果是 00即 0。
12 ---- 1 这里使用的是逻辑与运算符它是逻辑运算符用于判断两个条件是否同时为真。在大多数编程语言中逻辑与会进行短路求值即如果第一个条件为假则不会再计算第二个条件直接返回假。因此12 中的 1 和 2 都被视为真因此结果是 1。
1|2 ----- 3 这里使用的是按位或|运算符对应二进制的每一位进行或操作。1 的二进制表示为 012 的二进制表示为 10。按位或操作后得到的结果是 11即 3。
1||2 ---- 1 这里使用的是逻辑或||运算符用于判断两个条件是否有一个为真。逻辑或也会进行短路求值即如果第一个条件为真则不会再计算第二个条件直接返回真。因此1||2 中的 1 被视为真因此结果是 1。
在很多编程语言中比如 C、C、Java 等“” 是逻辑与运算符logical AND operator。当使用 “” 运算符时它会对两个条件进行逻辑与操作只有当两个条件都为真时整个表达式的结果才为真true否则结果为假false。
在上述表达式12 中1 和 2 被视为条件即非零值被视为真。因此根据逻辑与运算符的规则只有当两个条件都为真时结果才为真。在这种情况下1 和 2 都被视为真所以整个表达式的结果为真即 1。
一道笔试题
#include stdio.h
int main()
{int i 0, a 0, b 2, c 3, d 4;i a b d;//i a||b||d;printf(a %d\n b %d\n c %d\nd %d\n, a, b, c, d);return 0;
}现在我们来分析代码的执行过程
初始时a 0, b 2, c 3, d 4。 执行 i a b d 首先计算 aa 先赋值给 ii 0然后 a 自增为 1。此时 a 的值为 0表示为假。 因为第一个条件已经为假后续的条件不再执行即 b 和 d 都不会被执行。 整个表达式因为第一个条件为假所以结果为假即 i 的值为 0。 因此最终输出的结果是
a 1
b 2
c 3
d 4但是如果是注释掉的那一行那么结果为
a 1b 3c 3
d 4逗号表达式
逗号表达式会依次计算每个表达式并返回最后一个表达式的值作为整个表达式的值。
例如
//代码1
int a 1;
int b 2;
int c (ab, ab10, a, ba1);//逗号表达式
c是多少c为13
访问结构体
#include stdio.h
struct Stu
{char name[10];int age;char sex[5];double score;
}
void set_age1(struct Stu stu)
{stu.age 18;
}
void set_age2(struct Stu* pStu)
{pStu-age 18;//结构成员访问
}
int main()
{struct Stu stu;struct Stu* pStu stu;//结构成员访问stu.age 20;//结构成员访问set_age1(stu);pStu-age 20;//结构成员访问set_age2(pStu);return 0;
}这段代码中首先定义了一个结构体 Stu包括姓名、年龄、性别和分数四个成员变量。然后定义了两个函数 set_age1 和 set_age2分别用来设置学生的年龄。在 main 函数中创建了一个 Stu 类型的对象 stu并创建了一个指向该对象的指针 pStu。
接下来分析代码的执行过程
stu.age 20; // 将 stu 的年龄设置为 20set_age1(stu); // 传递参数时会复制结构体所以在 set_age1 函数中对参数进行的修改不会影响原始的 stu 对象。pStu-age 20; // 通过指针 pStu 访问 age 成员将年龄设置为 20set_age2(pStu); // 传递指针参数可以直接修改原始的结构体对象。
因此经过上述步骤后stu 对象的年龄应该是 20而 pStu 指向的对象的年龄应该是 18。所以最终输出的结果是stu.age 20pStu-age 18。
大小端
大小端Endian是指在存储多字节数据时字节序的不同排列方式。主要有两种类型大端序Big-endian和小端序Little-endian。
大端序Big-endian数据的高位字节存储在低地址低位字节存储在高地址。即数据的最高有效字节存储在最低的地址依次类推。
举例十六进制数 0x12345678 在大端序中存储为
地址 数据
0x00 - 12
0x01 - 34
0x02 - 56
0x03 - 78小端序Little-endian数据的低位字节存储在低地址高位字节存储在高地址。即数据的最低有效字节存储在最低的地址依次类推。
举例十六进制数 0x12345678 在小端序中存储为
地址 数据
0x00 - 78
0x01 - 56
0x02 - 34
0x03 - 12在计算机系统中不同的处理器架构采用不同的字节序而网络通信和数据交换等需要统一字节序以确保数据正确传输和解析。因此在跨平台开发和数据通信时需要注意数据的字节序问题。
为什么要存在大小端
大小端的存在主要是由于不同的计算机体系结构和处理器架构在存储和处理多字节数据时的方式不同。以下是一些原因 处理器架构差异不同的处理器架构采用了不同的字节序。例如x86 架构使用小端序而某些 RISC 架构如 ARM、PowerPC使用大端序。这种差异导致在进行跨平台开发、数据交换和网络通信时需要考虑字节序的转换。 数据传输在网络通信中不同的系统之间需要传输数据。为了确保数据的正确传输和解析发送方和接收方需要在数据传输过程中统一字节序。否则接收方可能会错误地解释数据导致数据损坏或解析错误。 数据存储在文件和存储设备上存储数据时字节序的一致性也很重要。如果不同系统上的程序读取和写入数据时使用不同的字节序那么数据的解析将会出错。
因此大小端的存在是为了解决不同系统间数据交换和解析的问题确保数据的正确性和一致性。
判断大小端的程序
#includestdio.h
#includewindows.h
int main()
{union{int a;char c;}un;un.a 1;if (un.c) {printf(小端\n);}else {printf(大端\n);}system(pause);return 0;
}解释 这段代码使用了 C 语言中的联合union来判断当前系统的字节序是大端序还是小端序。具体解释如下
定义了一个联合 un其中包含一个整型变量 a 和一个字符变量 c。将整型变量 a 赋值为 1。利用联合的特性修改 a 的同时也会影响到 c因为它们共享同一块内存空间。判断 c 的值如果 c 的值为非零则说明当前系统采用小端序如果 c 的值为 0则说明当前系统采用大端序。最后通过打印输出来显示当前系统的字节序。
整型提升
整型提升的意义 表达式的整型运算要在CPU的相应运算器件内执行CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度同时也是CPU的通用寄存器的长度。
因此即使两个char类型的相加在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
通用CPUgeneral-purpose CPU是难以直接实现两个8比特字节直接相加运算虽然机器指令中可能有这种字节相加指令。所以表达式中各种长度可能小于int长度的整型值都必须先转换为int或unsigned int然后才能送入CPU去执行运算。
整形提升是按照变量的数据类型的符号位来提升的。
//负数的整形提升
char c1 -1;
变量c1的二进制位(补码)中只有8个比特位
1111111
因为 char 为有符号的 char
所以整形提升的时候高位补充符号位即为1
提升之后的结果是
11111111111111111111111111111111//正数的整形提升
char c2 1;
变量c2的二进制位(补码)中只有8个比特位
00000001
因为 char 为有符号的 char
所以整形提升的时候高位补充符号位即为0
提升之后的结果是
00000000000000000000000000000001
//无符号整形提升高位补0用一个例子来体会一下
#includestdio.h
//实例1
int main()
{char a 0xb6;short b 0xb600;int c 0xb6000000;if (a 0xb6)printf(a);if (b 0xb600)printf(b);if (c 0xb6000000)printf(c);return 0;
}上述代码的速出结果为 c 因为 a,b 要进行整形提升,但是c不需要整形提升 a,b整形提升之后,变成了负数,所以表达式a0xb6 , b0xb600 的结果是假,但是c不发生整形提升,则表达式 c0xb6000000 的结果是真。
另一个例子
#includestdio.h
//实例2
int main()
{char c 1;printf(%u\n, sizeof(c));printf(%u\n, sizeof(c));printf(%u\n, sizeof(!c));return 0;
}结果分析 sizeof ( c )c 是一个字符型变量占用一个字节。所以 sizeof© 的结果是 1。 sizeof(c)在 C 语言中一元正号操作符会将操作数提升为整数类型。因此c 的结果将是一个 int 类型占用 4 个字节。所以 sizeof(c) 的结果应该是 4 而不是 1。 sizeof(!c)逻辑非操作符 ! 会返回 0 或 1而不改变数据类型的大小。所以 sizeof(!c) 的结果应该是 1。 表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof© ,就是1个字节
截断
截断truncation是指将一个值的小数部分舍弃只保留整数部分的操作。截断通常发生在从浮点数到整数的类型转换过程中。 如果将字节多的数据类型赋给一个占字节少的变量类型会发生“截断”。
举例说明
将浮点数截断为整数
假设有一个浮点数 x 3.75通过截断操作可以将其转换为整数 3。小数部分 .75 被舍弃只保留了整数部分 3。可以使用不同的编程语言提供的截断函数或类型转换函数来进行这样的操作例如在 Python 中使用 int() 函数或在 C 语言中使用 (int) 强制类型转换。
截断位操作
在计算机领域有时候我们需要对二进制数进行截断操作。例如假设有一个 8 位的二进制数 10101101如果我们只需要保留前 4 位那么截断操作就可以将其变为 1010。在具体实现中可以通过与运算bitwise AND来实现截断位操作。例如在 C 语言中可以使用按位与操作符 如 result number 0xF0其中 number 是原始的二进制数0xF0 是一个掩码表示前 4 位都为 1其余位都为 0。这样的截断操作就可以保留目标位上的数值。
举个例子
#includestdio.h
#includewindows.h
int main()
{ char a -1;signed char b -1;unsigned char c -1;printf(a%d,b%d,c%d\n, a, b, c);system(pause);return 0;
}以上代码的输出结果是 a-1, b-1, c255
这是因为在C语言中char类型默认被定义为有符号类型signed char其取值范围为-128到127。当使用-1赋值给char类型变量a时会将-1视为有符号数因此a的值也为-1。
而对于signed char类型的变量b虽然也是将-1赋值给它但由于已经明确指定为有符号类型所以它的值仍然是-1。
对于unsigned char类型的变量c它是无符号类型其取值范围为0到255。当将-1赋值给unsigned char类型变量c时会发生截断操作。由于c是无符号类型截断后的结果相当于对256取余即-1256255。因此c的值为255。