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

C语言基础(day0424)

目录

一. 键盘输入

1.1 grtchar()

1.2 scanf()

总结:

二. 全局变量/局部变量(函数的分类)

1.全局变量

2.局部变量 

三.C语言内存模型(堆栈内存and so on )

3.1 栈区(stack)(未完待续.....)

3.2 堆区

3.3 全局静态区

1. 未初始化

2. 已初始化

3.4 常量区

3.5 代码区

四.基本数据类型的转换

4.1 自动转换

4.2 强制转换

4.3 数据类型的精度

五. 运算符 

1. 算数运算符

2. 比较运算符

3. 赋值运算符

4. 自增运算符

5. 逻辑运算符

6. 条件运算符(三目运算符)

7. 逗号运算符

8. 运算符优先级(未完待续.....)

9. 位运算符

1. 补码的核心定义

2. 按位取反 (~) 的本质

3. 按位取反步骤(公式为~ a = -(a + 1))


一. 键盘输入

1.1 grtchar()

getchar() 函数用于从标准输入中读取一个字符,返回值为读取的字符。
getchar() 函数会等待用户输入一个字符并按下回车键,然后返回该字符的 ASCII 值。

//  这是一个简单的 getchar()示例,getchar只能读取数据类型为字符的变量// getchar() 函数用于从标准输入中读取一个字符,返回值为读取的字符。// getchar() 函数会等待用户输入一个字符并按下回车键,然后返回该字符的 ASCII 值。printf("请输入一个字符:\n");printf("请输入一个字符:\n");char ch = getchar();                // 使用 getchar 获取一个字符输入,并将其存储到变量 ch 中printf("您输入的字符是:%c\n", ch); // 输出用户输入的字符

1.2 scanf()

1. 使用 scanf 函数从标准输入中读取数据需要包含 stdio.h 头文件
2. scanf() 函数用于从标准输入中读取数据,格式为 scanf("格式控制字符串", 参数列表),类似于 printf() 的格式化输出。

3. 谨防 “空格陷阱” 。

#include <stdio.h>
int main(int argc, char const *argv[])
{//  这是一个简单的 printf() 示例printf("请输入一个字符:\n");printf("请输入一个字符:\n");char ch = getchar();            // 使用 getchar 获取一个字符输入,并将其存储到变量 ch 中printf("您输入的字符是:%c\n", ch); // 输出用户输入的字符// 使用 scanf 函数从标准输入中读取数据需要包含 stdio.h 头文件// scanf() 函数用于从标准输入中读取数据,格式为 scanf("格式控制字符串", 参数列表),类似于 printf() 的格式化输出。// 常见的格式化输入符号包括:%d(整数),%f(浮点数),%c(字符),%s(字符串),%x(十六进制整数),%o(八进制整数),%p(指针地址)。printf("请输入一个整数:\n");int num = 0;                       // 定义一个整数变量 num 并初始化为 0// 使用 scanf() 函数从标准输入中读取整数并存储到 num 中scanf("%d", &num);                 // 使用 scanf 函数从标准输入中读取一个整数并存储到 num 中printf("您输入的整数是:%d\n", num); // 输出用户输入的整数printf("请输入一个字符类型变量:\n");char c1;                        // 定义一个字符变量 c1scanf("%c", &c1);               // 使用 scanf 函数从标准输入中读取一个字符并存储到 c1 中printf("您输入的字符是:%c\n", c1); // 输出用户输入的字符// 使用 scanf() 函数从标准输入中读取多个变量的值printf("请输入两个变量的值(一个整数和一个浮点数):\n");int a = 0;                                       // 定义一个整数变量 a 并初始化为 0float b = 0.0;                                   // 定义一个浮点数变量 b 并初始化为 0.0scanf("%d %f", &a, &b);                          // 使用 scanf 函数从标准输入中读取一个整数和一个浮点数,并存储到变量 a 和 b 中printf("您输入的整数是:%d,浮点数是:%f\n", a, b); // 输出用户输入的整数和浮点数return 0;
}
总结:
  • 空格在 scanf 中的行为:匹配输入中的任意数量空白字符(包括零个或多个)。

  • 格式字符串中的普通字符:必须严格匹配输入流中的字符。

  • 最佳实践

    • 谨慎使用格式字符串中的空格。

    • 结合 fgets 和 sscanf 处理输入,避免缓冲区残留问题。

    • 始终检查 scanf 的返回值,确保输入符合预期。

二. 全局变量/局部变量(函数的分类)

1.全局变量

  (1)即作用于代码运行全过程的变量

  (2)具体演示,在下方代码

#include <stdio.h>// 全局变量..........所有函数都可以访问
// 全局变量如果未赋值,分配的默认值根据数据类型的不同而不同
// 全局变量耦合度高,容易引起错误,使用时要小心
/*int类型的全局变量默认值为0float类型的全局变量默认值为0.000000char类型的全局变量默认值为'\0'double类型的全局变量默认值为0.000char类型的全局变量默认值为'\0'short类型的全局变量默认值为0long类型的全局变量默认值为0*/
int globalVar = 10; // 全局变量,作用域为整个文件,与函数平级void function()
{// 局部变量int localVar = 5; // 局部变量,作用域仅限于此函数内printf(" 函数内 局部变量 localVar 的值: %d\n", localVar);printf(" 函数内 全局变量 globalVar 的值: %d\n", globalVar);
}int main()
{printf("全局变量 globalVar 的值: %d\n", globalVar); // 可以访问全局变量function();                                         // 调用上方的函数// printf("局部变量 localVar 的值: %d\n", localVar); // 这行代码会报错,因为 localVar 作用域仅限于 function 函数return 0;
}

2.局部变量 

  (1)即作用于部分代码块的变量

  (2)具体演示,在下方代码

#include <stdio.h>// 局部变量示例:演示局部变量的初始化和使用
// 局部变量未初始化时,其默认值是未定义的,因为普通局部变量存储在栈空间中,包含之前的随机数据。
int main()
{// 未初始化的局部变量-----------注意其默认值是未定义的int localVar; // 局部变量声明但未初始化printf("未初始化的局部变量 localVar 的值: %d\n", localVar);// 初始化局部变量-----------默认值为0localVar = 0;localVar = 0; // 初始化局部变量,将其值设置为0printf("初始化后的局部变量 localVar 的值: %d\n", localVar);// 在同一个函数中,局部变量可以重复使用// int localVar = 5; // 如果这样写会报错,因为 localVar 已经在上面声明过,并且已经使用 int 在栈中分配了空间// printf("在同一个函数中,局部变量可以重复使用,但需要注意不能重新声明同名变量。");// 在同一个函数中,可以使用同名的变量,但需要使用不同的作用域localVar = 5; // 修改局部变量的值为5printf("修改后的局部变量 localVar 的值: %d\n", localVar);return 0;
}

三.C语言内存模型(堆栈内存and so on )

内存分为五个模块,我们常用的int在内存开辟空间,其实就是,在内存呢的栈区开辟了空间byte为4.

3.1 栈区(stack)(未完待续.....)

1. 先进后出(filo模式),即电梯,弹夹

2. 表现形式为倒扣水杯,口朝下(上方闭口为栈底,开口处为栈顶,先进为高地址,反之为底)

3. 未初始化的变量,会覆盖掉之前的栈帧(那么意思就是栈帧是不会立刻消失,在内存中仍有痕迹)

3.2 堆区

3.3 全局静态区

未完待续......

1. 未初始化

未完待续......

2. 已初始化

未完待续......

3.4 常量区

未完待续......

3.5 代码区

未完待续......

四.基本数据类型的转换

1. 自动类型转换:当同意表达式中有不同类型的变量时,编译器会自动将低精度类型转换为高精度类型,然后进行运算。

2. 强制类型转换:使用强制类型转换运算符将一种数据类型转换为另一种数据类型。

3. 数据类型的转换不会影响数据本身的值,只是改变了数据在内存中的存储方式。

4.1 自动转换

 int a = 5;float b = 2.5;double c = 3.5;// 自动类型转换double result = a + b + c;                // int -> float -> double,printf("自动类型转换结果: %f\n", result); // 输出结果为 11.000000,%f表示浮点数格式输出,默认保留6位小数

4.2 强制转换

/*强制类型转换int -> float -> double*/int d = 5;float e = 2.5;double f = 3.5;// 强制类型转换double result2 = (double)d + (double)e + (double)f; // int -> float -> doubleprintf("强制类型转换结果: %f\n", result2);          // 输出结果为 11.000000,%f表示浮点数格式输出,默认保留6位小数// 再转为int类型int result3 = (int)result2;                         // double -> intprintf("强制类型转换结果: %d\n", result3);          // 输出结果为 11

4.3 数据类型的精度

      高精度类型:double、float、long double

      低精度类型:int、char、short、long

      高转低精度类型:基本不会失去精度,数据不会丢失。

      低转高精度类型:会失去精度,可能会导致数据丢失。

五. 运算符 

1. 算数运算符

用于基本数学运算。

运算符描述示例注意
+加法a + b
-减法a - b
*乘法a * b
/除法a / b整数除法会丢弃小数部分
%取模(余数)a % b只能用于整数,结果符号与被除数相同
++自增a++ 或 ++aa = ( a + 1 )
--自减a-- 或 --a同上
#include <stdio.h>// 实型是指小数的类型,整型是指整数的类型,字符型是指字符的类型
float f = 10.0; // 浮点型变量,表示小数类型
// 整形是指整数的类型,实型是指小数的类型,字符型是指字符的类型
int i = 10; // 整型变量,表示整数类型int main(int argc, char const *argv[])
{// 算数运算符// 正数负数int a = 10;int b = -10;printf("a = %d, b = %d\n", a, b);// 基本算数运算符int c = 20;int d = 10;float f1 = 5.5;float f2 = 10.5;printf("c + d = %d\n", c + d);  // 加法printf("c - d = %d\n", c - d);  // 减法printf("c * d = %d\n", c * d);  // 乘法printf("c / d = %d\n", c / d);  // 除法,除数不能为0printf("c %% d = %d\n", c % d); // 取余,此处需要用%%来转义%,因为%是格式化输出的标志,取小数点后1位的值,不能对0取余,除数不能为0// 1. 先乘除后加减printf("c + d * 2 = %d\n", c + d * 2);// 2. 先乘除后加减,括号内的优先级最高printf("c + d * 2 = %d\n", (c + d) * 2); // 先加减后乘除,括号内的优先级最高// 3. 两个整数相除,结果是整数,取整printf("c / d = %d\n", c / d); // 结果是整数,取整// 4. 两个浮点数相除,结果是浮点数,保留小数点后6位printf("f1 / f2 = %f\n", f1 / f2); // 结果是浮点数,保留小数点后6位// 5. 整数和浮点数相除,结果是浮点数,保留小数点后6位printf("c / f1 = %f\n", c / f1); // 结果是浮点数,保留小数点后6位// 6. 取余运算符%只能用于整数之间的运算,不能用于浮点数之间的运算// printf("f1 %% f2 = %f\n", f1 % f2); // 错误,取余运算符%只能用于整数之间的运算,不能用于浮点数之间的运算// 7. 对负数取余,正整数的余数是正数,负整数的余数是负整数printf("b %% d = %d\n", b % d); // 结果是负整数,取余运算符%只能用于整数之间的运算,不能用于浮点数之间的运算return 0;
}

2. 比较运算符

 比较运算符:==、!=、>、<、>=、<=

    ==:相等运算符,判断两个值是否相等(与赋值运算符=不同)
    !=:不相等运算符,判断两个值是否不相等
    >: 大于运算符,判断左边的值是否大于右边的值
    <: 小于运算符,判断左边的值是否小于右边的值
    >=:大于等于运算符,判断左边的值是否大于或等于右边的值
    <=:小于等于运算符,判断左边的值是否小于或等于右边的值
    注意:比较运算符的结果是布尔值(0或1),0表示假,1表示真。


用于比较两个值,返回 1(真)或 0(假)。

运算符描述示例注意
==等于a == b不要与 = 混淆
!=不等于a != b
>大于a > b
<小于a < b
>=大于等于a >= b
<=小于等于a <= b

#include <stdio.h>
int main(int argc, char const *argv[])
{/*比较运算符:==、!=、>、<、>=、<===:相等运算符,判断两个值是否相等(与赋值运算符=不同)!=:不相等运算符,判断两个值是否不相等>: 大于运算符,判断左边的值是否大于右边的值<: 小于运算符,判断左边的值是否小于右边的值>=:大于等于运算符,判断左边的值是否大于或等于右边的值<=:小于等于运算符,判断左边的值是否小于或等于右边的值注意:比较运算符的结果是布尔值(0或1),0表示假,1表示真。*/int a = 10, b = 20;printf("a == b: %d\n", a == b); // 相等(==)运算符 返回值0,表示假printf("a != b: %d\n", a != b); // 不相等(!=)运算符 返回值1,表示真printf("a > b: %d\n", a > b);   // 大于(>)运算符 返回值0,表示假printf("a < b: %d\n", a < b);   // 小于(<)运算符 返回值1,表示真printf("a >= b: %d\n", a >= b); // 大于等于(>=)运算符 返回值0,表示假printf("a <= b: %d\n", a <= b); // 小于等于(<=)运算符 返回值1,表示真./*比较运算符自身的优先级低于算术运算符和位运算符,但高于逻辑运算符。例如:在表达式 a + b > c && d < e 中,首先计算 a + b 和 d < e,然后再进行逻辑与运算。*/int c = 30, d = 40, e = 50;printf("a + b > c && d < e: %d\n", (a + b > c) && (d < e)); // 返回值1,表示真/*算数运算符的优先级高于比较运算符,但低于逻辑运算符。例如:在表达式 a + b > c && d < e 中,首先计算 a + b 和 d < e,然后再进行逻辑与运算。*/printf("a + b > c && d < e: %d\n", (a + b > c) && (d < e)); // 返回值1,表示真return 0;
}

3. 赋值运算符

 赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
         =:  赋值运算符,将右边的值赋给左边的变量
        +=: 加法赋值运算符,将右边的值加到左边的变量上,并将结果赋给左边的变量
        -=:  减法赋值运算符,将右边的值减去左边的变量,并将结果赋给左边的变量
        *=:  乘法赋值运算符,将右边的值乘以左边的变量,并将结果赋给左边的变量
        /=:   除法赋值运算符,将左边的变量除以右边的值,并将结果赋给左边的变量
        %=: 取余赋值运算符,将左边的变量除以右边的值,并将余数赋给左边的变量
        &=:  按位与赋值运算符,将左边的变量和右边的值进行按位与运算,并将结果赋给左边的变量
        |=: 按位或赋值运算符,将左边的变量和右边的值进行按位或运算,并将结果赋给左边的变量
        ^=: 按位异或赋值运算符,将左边的变量和右边的值进行按位异或运算,并将结果赋给左边的变量
        <<=:左移赋值运算符,将左边的变量左移右边的位数,并将结果赋给左边的变量
        >>=:右移赋值运算符,将左边的变量右移右边的位数,并将结果赋给左边的变量
        注意:赋值运算符,会修改变量的原始值 

用于给变量赋值。

运算符描述示例等价于
=简单赋值a = 5
+=加后赋值a += 3a = a + 3
-=减后赋值a -= 2a = a - 2
*=乘后赋值a *= 4a = a * 4
/=除后赋值a /= 2a = a / 2
%=取模后赋值a %= 3a = a % 3
#include <stdio.h>
int main(int argc, char const *argv[])
{/*赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>==: 赋值运算符,将右边的值赋给左边的变量+=: 加法赋值运算符,将右边的值加到左边的变量上,并将结果赋给左边的变量-=: 减法赋值运算符,将右边的值减去左边的变量,并将结果赋给左边的变量*=: 乘法赋值运算符,将右边的值乘以左边的变量,并将结果赋给左边的变量/=: 除法赋值运算符,将左边的变量除以右边的值,并将结果赋给左边的变量%=: 取余赋值运算符,将左边的变量除以右边的值,并将余数赋给左边的变量&=: 按位与赋值运算符,将左边的变量和右边的值进行按位与运算,并将结果赋给左边的变量|=: 按位或赋值运算符,将左边的变量和右边的值进行按位或运算,并将结果赋给左边的变量^=: 按位异或赋值运算符,将左边的变量和右边的值进行按位异或运算,并将结果赋给左边的变量<<=:左移赋值运算符,将左边的变量左移右边的位数,并将结果赋给左边的变量>>=:右移赋值运算符,将左边的变量右移右边的位数,并将结果赋给左边的变量注意:赋值运算符,会修改变量的原始值*/// 赋值运算符,将右边的值赋给左边的变量// 复合赋值运算符,将右边的值加到左边的变量上,并将结果赋给左边的变量double a = 888888.88;a += 11.11;printf("a += 11.11: %f\n", a); // 888899.99// 等价于i= i%(j-2),=后面是一个整体int i = 10, j = 20;i += i % (j - 2);                     // i = i + i % (j - 2)printf("i += i %% (j - 2): %d\n", i); // 10 + 10 % (20 - 2) = 10 + 10 % 18 = 10 + 10 = 20// 比较运算符的优先级低于算术运算符和位运算符,但高于逻辑运算符。printf("i + j > i && i < j: %d\n", (i + j > i) && (i < j)); // 意思是 i + j > i 和 i < j 同时成立才返回真,i + j > i 的值为真,i < j 的值为假,所以结果为假// 先乘除后加减,括号内的优先级最高return 0;
}

4. 自增运算符

        自增运算符:++,自减运算符:--
        ++: 自增运算符,将变量的值加1,并将结果赋给变量本身
        --: 自减运算符,将变量的值减1,并将结果赋给变量本身
        注意:自增和自减运算符的优先级高于赋值运算符,但低于算术运算符和位运算符。
        注意:不能用于常量和表达式,只能用于变量。
        注意:自增和自减运算符可以放在变量的前面或后面,前缀和后缀的区别在于自增和自减的顺序。 


运算符描述示例区别
a++后置自增int b = a++;先使用 a 的值,再自增
++a前置自增int b = ++a;先自增 a,再使用新值
a--后置自减int b = a--;同上逻辑
--a前置自减int b = --a;同上逻辑
#include <stdio.h>
int main(int argc, char const *argv[])
{/*自增运算符:++,自减运算符:--++: 自增运算符,将变量的值加1,并将结果赋给变量本身--: 自减运算符,将变量的值减1,并将结果赋给变量本身注意:自增和自减运算符的优先级高于赋值运算符,但低于算术运算符和位运算符。注意:不能用于常量和表达式,只能用于变量。注意:自增和自减运算符可以放在变量的前面或后面,前缀和后缀的区别在于自增和自减的顺序。*/// 自增运算符,将变量的值加1,并将结果赋给变量本身 (a++)int a = 10;int b = 20;a++; // a = a + 1; // 先赋值后自增++b; // b = b + 1; // 先自增后赋值--bprintf("a++: %d\n", a); // 11printf("--b: %d\n", b);printf("++b: %d\n", b); // 21// 自减运算符,将变量的值减1,并将结果赋给变量本身 (a--)int c = 10;int d = 20;c--;                    // c = c - 1; // 先赋值后自减--d;                    // d = d - 1; // 先自减后赋值printf("c--: %d\n", c); // 9printf("--d: %d\n", d); // 19// 自增和自减运算符高于算数运算符和位运算符,但低于赋值运算符。int e = 3 * ++b;              // 先处理++b,b = 21 + 1 = 22,然后再处理3*22 = 66printf("e = 3*++b: %d\n", e); // 66return 0;
}

5. 逻辑运算符

    逻辑运算符:&&、||、!
    逻辑与:&&,当且仅当两个操作数都为真时,结果才为真。
    逻辑或:||,当至少有一个操作数为真时,结果为真
    逻辑非:!,对操作数取反,真变假,假变真。
    逻辑运算符的优先级:! > && > || 


用于组合或反转布尔表达式。

运算符描述示例规则(短路求值)
&&逻辑与a && b全为真则真,否则假
||逻辑或a || b任意为真则真,否则假
!逻辑非!a反转布尔值
#include <stdio.h>
int main(int argc, char const *argv[])
{/*逻辑运算符:&&、||、!逻辑与:&&,当且仅当两个操作数都为真时,结果才为真。逻辑或:||,当至少有一个操作数为真时,结果为真逻辑非:!,对操作数取反,真变假,假变真。逻辑运算符的优先级:! > && > ||*/// 逻辑与运算符:&&//短路机制:如果第一个操作数为假,则不计算第二个操作数int a = 1, b = 2, c = 3;// 逻辑与运算符的优先级高于赋值运算符,所以先计算逻辑与运算符printf(a > 0 && b > 0 && c > 0 ? "a、b、c都是正数\n" : "a、b、c不是正数\n");// 逻辑或运算符:||//短路机制:如果第一个操作数为真,则不计算第二个操作数printf(a > 0 || b > 0 || c > 0 ? "a、b、c至少有一个是正数\n" : "a、b、c都不是正数\n");// 逻辑非运算符:!printf(a != 0 ? "a不是0\n" : "a是0\n"); // a不是0// 逻辑运算符的优先级:! > && > ||// 逻辑与运算符的优先级高于逻辑或运算符,所以先计算逻辑与运算符if (a > 0 && b > 0 || c > 0){printf("a、b、c至少有一个是正数\n");}else{printf("a、b、c都不是正数\n");}return 0;
}

6. 条件运算符(三目运算符)

唯一的三元运算符,用于简化条件判断。

语法描述
条件 ? 表达式1 : 表达式2若条件为真,返回表达式1,否则返回表达式2
#include <stdio.h>
int main(int argc, char const *argv[])
{/*条件运算符:?:,也称为三目运算符,语法格式为:条件表达式 ? 表达式1 : 表达式2条件表达式为真时,返回表达式1的值;条件表达式为假时,返回表达式2的值。attention:条件运算符的优先级低于赋值运算符,所以在使用条件运算符时,要注意括号的使用。条件运算符的优先级:?: > = > + - > * / %三目运算符返回值的类型由表达式1和表达式2决定,如果表达式1和表达式2的类型不同,则返回值的类型为更高的类型。条件运算符的返回值可以作为赋值语句的右值,也可以作为函数的参数。*/// 条件运算符int a = 1, b = 2, c = 3;(a > b) ? printf("a大于b\n") : printf("a小于等于b\n");// 条件运算符的优先级低于赋值运算符,所以要加括号c = (a > b) ? a : b; // 如果a大于b,则b等于a,否则b等于bprintf("b = %d\n", b);return 0;
}

7. 逗号运算符

用于分隔多个表达式,返回最后一个表达式的值。

语法描述
表达式1, 表达式2依次执行表达式1和表达式2,返回表达式2的值
#include <stdio.h>
int main(int argc, char const *argv[])
{/*逗号运算符:,,逗号运算符的优先级最低,逗号运算符的左操作数和右操作数都要计算,返回右操作数的值。*/int a = 3;int b = (a++, ++a, a + 5); // 逗号运算符的优先级最低,逗号运算符的左操作数和右操作数都要计算,返回右操作数的值。printf("a = %d\n", a);     // a = 5printf("b = %d\n", b);     // b = 10int a = 3;int b = ((a + a), a + 5);printf("a = %d\n", a);printf("b = %d\n", b);return 0;
}

8. 运算符优先级(未完待续.....)

不必理会

#include <stdio.h>
int main(int argc, char const *argv[])
{/*逗号<赋值<逻辑(不包含非)<比较<算数*/// 案例一int x = 0, y = 1;int res = x++ != !y;return 0;
}

9. 位运算符

按位取反:

   其余的暂时不用进行描述,简单易懂,在这里只对按位取反进行描述。

1. 补码的核心定义

在计算机中,所有整数均以补码形式存储,补码规则如下:

  • 正数:补码 = 原码(二进制直接表示,符号位为0)。

  • 0111 1111 1111 1111 1111 1111 1111 1111

  • 负数:补码 = 原码取反(反码) + 1(符号位为1)。

  • 1000 0000 0000 0000 0000 0000 0000 0000


2. 按位取反 (~) 的本质
  • 操作对象:直接对整数的补码逐位取反(包括符号位)。

  • 结果类型:结果仍为补码,需转换回原码才能得到十进制值。

3. 按位取反步骤(公式为~ a = -(a + 1))
  • 取补码 (正数的补码为原码)

  • 对补码进行取反(0为1,1为0)

  • 取反过的补码转原码(负数的转换规则)

  • 补码 → 原码(符号位为1,说明是负数)

  • 符号位不变,其他位取反 → 得到原码

  • 算出结果。

#include <stdio.h>
int main(int argc, char const *argv[])
{/*位运算原码:符号位+绝对值0:0000 0000 0000 0000 0000 0000 0000 00001:0000 0000 0000 0000 0000 0000 0000 0001-1:1000 0000 0000 0000 0000 0000 0000 0001-2:1000 0000 0000 0000 0000 0000 0000 00104:0000 0000 0000 0000 0000 0000 0000 0100 反码:符号位+绝对值的反码3:0000 0000 0000 0000 0000 0000 0000 0011-3:1111 1111 1111 1111 1111 1111 1111 1100补码:符号位+绝对值的补码3:0000 0000 0000 0000 0000 0000 0000 0011-3:1000 0000 0000 0000 0000 0000 0000 0011位运算是c语言中一种直接对二进制位进行操作的运算符,位运算符有:按位与:&,按位或:|,按位异或:^,按位取反:~,左移:<<,右移:>>。*/// 1. 按位与:& (二进制对应位都为1时候,新结果二进制对应位才为1,否则为0)int a = 3;                 // 0011int b = 5;                 // 0101int c = a & b;             // 0001printf("a & b = %d\n", c); // 1/*示例*/int a1 = 4;                   // 0100int b1 = 5;                   // 0101int c1 = a1 & b1;             // 0100printf("a1 & b1 = %d\n", c1); // 4// 0100 & 0101 = 0100// 2. 按位或:| (两个都为0的时候才为0,否则为1)c = a | b;                 // 0111printf("a | b = %d\n", c); // 7/*示例int a1 = 4;    0100             int b1 = 5;    0101           */c1 = a1 | b1;  // 0101printf("a1 | b1 = %d\n", c1); // 5// 3. 按位异或:^ (两个相同为0,不同为1)c = a ^ b;                 // 0110printf("a ^ b = %d\n", c); // 6/*示例int a1 = 4;    0100             int b1 = 5;    0101           */c1 = a1 ^ b1;  // 0001printf("a1 ^ b1 = %d\n", c1); // 1// 4. 按位取反:~ //公式为~a = -(a + 1 );c = ~a;                 // 1100 ,将1100转为十进制,即1100-1=1100-1=-4printf("~a = %d\n", c); // -4,注意:按位取反是对补码进行操作的,所以结果是负数/*示例int a1 = 4;    0100   利用公式可得~a为-5*/c1 = ~a1;  // 1011 = -5printf("~a1 = %d\n", c1); // -5,注意:按位取反是对补码进行操作的,所以结果是负数// 5. 左移:<< (左移n位,相当于乘以2^n)c = a << 1;                 // 原本为0011,左移之后为0110printf("a << 1 = %d\n", c); // 6// 6. 右移:>> (右移n位,相当于除以2^n)c = a >> 1;                 // 原本为0011,0001printf("a >> 1 = %d\n", c); // 1// 7.位运算场景,例如:交换两个数的值 (两个相同为0,不同为1)int x = 3, y = 5;printf("x = %d, y = %d\n", x, y); // x = 3, y = 5,交换前x = x ^ y;                        // x = 3 ^ 5 = 6,5 = 0101,3 = 0011,结果为0110y = x ^ y;                        // y = 6 ^ 5 = 3,6 = 0110,5 = 0101,结果为0011x = x ^ y;                        // x = 6 ^ 3 = 5,6 = 0110,3 = 0011,结果为0101printf("x = %d, y = %d\n", x, y); // x = 5, y = 3,交换成功return 0;
}

相关文章:

  • AI打开潘多拉魔盒?当深度伪造成为虚假信息的核动力引擎
  • 仓库体系结构风格-笔记
  • Unity 资源合理性检测
  • 数据完整性的守护者:哈希算法原理与实现探析
  • Python中random库的应用
  • ​Janus Pro
  • C++跨平台开发要点
  • 面试题:Java程序CPU 100%问题排查指南
  • Mermaid 绘图指南(二)- 使用 Typora 与 Mermaid 绘制专业图表
  • Qt 使用 MySQL 数据库的基本方法
  • redis集群的三种部署方式
  • 《ATPL地面培训教材13:飞行原理》——第1章:概述与定义
  • unity Animation学习,精准控制模型动画播放
  • Android PackageManagerService(PMS)框架深度解析
  • [创业之路-386]:企业法务 - 知识产权的刑事风险
  • 2025年3月电子学会青少年机器人技术(四级)等级考试试卷-理论综合
  • SpringBoot入门实战(第八篇:项目接口-订单管理)完结篇
  • 第九节:性能优化高频题-首屏加载优化策略
  • 类和对象(构造函数和析构函数)
  • 修改RK3568 UBUNTU开机画面
  • 政治局会议:要提高中低收入群体收入,设立服务消费与养老再贷款
  • 记录发生真相,南沙岛礁生态调查纪实片《归巢》发布
  • 朱守科任西藏自治区政府副主席、公安厅厅长
  • 谷歌一季度利润增超四成:云业务利润率上升,宏观环境可能影响广告业务
  • 限时离境、关闭领空、暂停贸易,巴基斯坦宣布一系列对印反制措施
  • 新东方:2025财年前三季度净利增29%,第四财季海外业务将承压