c语言基础3

[1]运算符

1.1 逻辑运算符

&& 逻辑与:全真则真,一假则假
|| 逻辑或:一真则真,全假则假
! 逻辑非:非真则假,非假则真

0为假   1为真
printf("%d\n",2>3); //0
printf("%d\n",22>3);//1

printf("%d\n",12>3&&8<6); //0
printf("%d\n",12>3||8<6); //1
printf("%d\n",12>3 && !(8<6)); //1

截断法则:
逻辑与运算中,前边的表达式结果为假,后边的表达式不再执行,直接返回假
逻辑或运算中,前边的表达式结果为真,后边的表达式不再执行,直接返回真
练习:

#include <stdio.h>
int main()
{
	int a=5,b=6,c=7,d=8,m=2,n=2;
	(m=a>b)&&(n=c>d);
	printf("%d  %d",m,n)//0  2
}

image.png

1.2位运算符

二进制数01
& |^ ~ << >>
& 位与:全1则1,有0则0
| 位或:有1则1,全0则0
^ 异或:相同为0,不同为1
~ 取反:1---->00------>1

image.png
image.png
实现两个变量值的交换:

int a=12,b=10;
int temp=0;
temp=a;
a=b;
b=temp;
printf("%d %d\n",a,b);

2)

a=a^b;//0110==6
b=a^b;//0110 1010 1100=12
a=a^b;//0110 1100 1010=10
printf("%d %d\n",a,b);

计算机中,整数以二进制的补码形式存储,计算的

原码、反码、补码

原码、反码、补码 解释原码、反码和补码是在计算机中用于表示有符号整数的三种不同方式。它们是用来处理负数的编码方式,常见于计算机系统中的位运算和算术运算。

1. 原码(Sign-Magnitude)

定义: 最简单直观的表示方式,其中最高位(最左边的位)表示符号位,0表示正数,1表示负数,其余位表示数值部分。

  • 例子: 对于一个8位有符号整数,正数和负数的原码表示如下:
    • +3 的原码: 00000011
    • -3 的原码: 10000011

特点:

  • 最高位为符号位,其余位表示数值部分。
  • 容易理解和实现,但对于运算中的溢出和零有特殊处理。

2. 反码(One’s Complement)

定义: 正数的反码与原码相同,负数的反码是对其原码除符号位外的每一位取反。

  • 例子: 使用8位有符号整数的反码表示如下:
    • +3 的反码: 00000011
    • -3 的反码: 11111100

特点:

  • 相对于原码,计算负数的反码简单,但存在两个零(正零和负零),且存在算术运算中的特殊情况。

3. 补码(Two’s Complement)

定义: 正数的补码与原码相同,负数的补码是其反码加1。

  • 例子: 使用8位有符号整数的补码表示如下:
    • +3 的补码: 00000011
    • -3 的补码: 11111101

特点:

  • 补码是计算机中最常用的有符号整数表示方式,它只有一个零(用全0表示),没有正零和负零的区分。
  • 计算机硬件可以使用补码快速执行加法和减法运算,且只需一组加法器实现。

比较和应用:

  • 原码是最直观的表示方式,但不适合运算。
  • 反码在一些历史系统中使用,如机器编码和传统硬件。
  • 补码是目前主流的表示方式,广泛用于现代计算机体系结构中,允许有效的运算和减少硬件实现成本。

在计算机中,CPU会根据具体的指令集来进行原码、反码、补码之间的转换和运算,这些码制对于程序员来说可能不需要直接处理,但了解其基本概念有助于理解整数运算和二进制表示的细节。

原码反码补码
正数相同相同相同
负数相同除符号位外,其他按位取反反码+1

int4字节=32位 1字节=8位
符号位:最左边0正数1负数
12:
00000000000000000000000000001100
-12:
10000000000000000000000000001100

int a=12,b=-10; //12:1100 10:1010
int c=a&b;
printf(“%d\n”,c); //4
12补码:
00000000000000000000000000001100
-10原码:
10000000000000000000000000001010
-10反码:
11111111111111111111111111110101
-10补码:
11111111111111111111111111110110
12补码&-10补码:
00000000000000000000000000001100
11111111111111111111111111110110
00000000000000000000000000000100===4

~取反:1–》00–>1
int a=7;
int c=~a;
printf(“%d\n”,c);//-8
=========================
7补码:
00000000000000000000000000000111
~:补码
111111111111111111111111111110001000=80111
反码:
11111111111111111111111111110111
原码:
10000000000000000000000000001000
=-8

<<左移

左移n位,右边补充n个0
image.png
6<<2==24 6 十进制数转换为2进制数
公式:
62^2=24 ^ 异或:相同为0,不同为1
-6
2^2=-24

>>右移

右移n位,最右边舍弃
6>>2==1
公式:
6/2^2=1
-6/2^2=-2 (小数点后大于直接进位) -1.5 -2 -1 -2

置一公式:a|(1<<n)
置零公式:a&(~(1<<n))
这两个公式看起来是关于位操作的。让我们逐个解释和如何在C语言中使用它们。

公式解释

  1. 置一公式: a | (1 << n)
    • 这个公式的作用是将变量 a 的第 n 位设为1,其余位保持不变。
    • 1 << n 表示将1左移 n 位,即在二进制中只有第 n 位为1,其余位为0。
    • | 操作符执行按位或操作,即两个相应位中只要有一个为1,则结果为1。
  2. 置零公式: a & (~(1 << n))
    • 这个公式的作用是将变量 a 的第 n 位设为0,其余位保持不变。
    • 1 << n 仍然是将1左移 n 位,产生一个只有第 n 位为1的值。
    • ~(1 << n) 是对 1 << n 的按位取反操作,即将其除了第 n 位外的所有位取反。
    • & 操作符执行按位与操作,即两个相应位中只有都为1时,结果为1。

在C语言中的使用

在C语言中,可以将这些公式直接用作赋值语句或者表达式的一部分。例如:

// 将变量 a 的第 n 位设为1
a = a | (1 << n);

// 将变量 a 的第 n 位设为0
a = a & (~(1 << n));

这里假设 a 是一个整数类型的变量,如 int 或者 unsigned int。这些操作是针对 a 的二进制表示进行的,直接影响其在内存中的比特位。

示例

假设 a 的二进制表示为 1010(十进制为10),我们想要将第2位(从右往左数,从0开始)设为1和0:

  1. 置一操作:
    • 初始 a 的二进制是 1010,执行 a | (1 << 2) 后,得到 1010 | (1 << 2) = 1010 | 0100 = 1110,即十进制为14。
  2. 置零操作:
    • 如果我们有 a1010,执行 a & (~(1 << 2)) 后,得到 1010 & (~(1 << 2)) = 1010 & 1011 = 1010,即十进制还是10,但第2位变成了0。

这些操作在嵌入式编程、位掩码操作等领域非常常见,可以高效地设置或清除特定的位,而无需修改其他位。
:::info
以下程序升输出结果是()。
int main()
{
char x=040; //1 000 000 ==0100
printf(“%o\n”,x<<1);
return 0;
}
A.100 B.80 C.64 D.32
:::
答案解析
在这个程序中,输出结果是 100
让我们详细解释一下:

  1. 变量初始化:

char x = 040;
这里的 040 是一个八进制数,转换为十进制是 32。因此,x 的值为 32

  1. 位左移操作:

printf(“%o\n”, x << 1);
x << 1 表示将 x 的二进制表示向左移动一位。对于 32 的二进制表示为 00100000,左移一位后变成 01000000

  1. 输出格式化:

printf(“%o\n”, x << 1);
%oprintf 格式化输出的控制字符,表示以八进制形式输出。因此,01000000 的八进制表示是 100
综上所述,程序运行后的输出结果是 100
image.png

image.png
答案解析当我们使用位左移操作符 << 时,它将一个数的二进制表示向左移动指定的位数。在C语言中,左移操作符的形式是 a << b,其中 a 是要进行移位的数,b 是要移动的位数。
对于题目中的情况:

  • 给定 a = 13
  • a << 2 的十进制数值

步骤解析:

  1. 确定 a 的二进制表示:
    • a = 13 的二进制表示是 1101
  2. 进行位左移操作 a << 2
    • 1101 向左移动两位。
  3. 左移操作的结果:
    • 移动后的结果是 110100
  4. 转换为十进制数值:
    • 110100 的二进制转换为十进制是 52

因此,a << 2 的十进制数值为 52

1.3关系运算符

=<<===!=
==等于 =赋值
2–9x>2&&x<9
关系运算符内容解析

关系运算符

在C语言中,关系运算符用于比较两个值,并返回一个布尔值(1表示真,0表示假)。

  1. 大于 (>):如果左操作数大于右操作数,则条件为真。
    • 示例:x > 2 表示 x 大于 2
  2. 大于等于 (>=):如果左操作数大于或等于右操作数,则条件为真。
    • 示例:x >= 2 表示 x 大于或等于 2
  3. 小于 (<):如果左操作数小于右操作数,则条件为真。
    • 示例:x < 9 表示 x 小于 9
  4. 小于等于 (<=):如果左操作数小于或等于右操作数,则条件为真。
    • 示例:x <= 9 表示 x 小于或等于 9
  5. 等于 (==):如果两个操作数相等,则条件为真。
    • 示例:x == 5 表示 x 等于 5
  6. 不等于 (!=):如果两个操作数不相等,则条件为真。
    • 示例:x != 0 表示 x 不等于 0

逻辑运算符

逻辑运算符用于组合和操作布尔值。

  • 逻辑与 (&&):如果两个操作数都为真,则条件为真。
    • 示例:x > 2 && x < 9 表示 x 大于 2 并且小于 9
  • 逻辑或 (||):如果两个操作数中有一个为真,则条件为真。
    • 示例:x < 2 || x > 9 表示 x 小于 2 或者大于 9
  • 逻辑非 (!):用于翻转操作数的逻辑状态。如果条件为真,则逻辑非将其变为假,反之亦然。
    • 示例:!(x == 5) 表示 x 不等于 5

示例

如果我们有一个变量 int x = 6;,我们可以使用上述关系运算符和逻辑运算符来进行条件判断:

if (x > 2 && x < 9) {
    // 如果 x 大于 2 并且小于 9,则执行这里的代码
    printf("x 在区间 (2, 9) 内\n");
} else {
    // 否则执行这里的代码
    printf("x 不在区间 (2, 9) 内\n");
}

这段代码将根据 x 的值判断是否在区间 (2, 9) 内,并输出相应的消息。

1.4三目运算符(选择运算符)

三目运算符 解析三目运算符,也称为条件运算符,是一种在很多编程语言中都存在的特殊运算符。它允许根据条件的真假来选择执行不同的操作或返回不同的值。

语法和用法

在大多数编程语言中,三目运算符的语法如下:

condition ? expr1 : expr2

其中:

  • condition 是一个布尔表达式或者可以转换为布尔值的表达式。
  • 如果 condition 为真,则整个表达式的值为 expr1
  • 如果 condition 为假,则整个表达式的值为 expr2

示例

让我们看一个简单的例子来说明三目运算符的用法:

int a = 10;
int b = 20;
int max = (a > b) ? a : b;

// 上述代码等效于以下的if-else语句:
// int max;
// if (a > b) {
//     max = a;
// } else {
//     max = b;
// }

printf("最大值是:%d\n", max);

在这个例子中,如果 a 大于 b,则 max 被赋值为 a;否则 max 被赋值为 b。在输出语句中,将打印出 max 的值,这里是 20

特点和注意事项

  • 简洁性: 三目运算符能够在简短的表达式中实现条件选择,比起使用 if-else 结构,它更加简洁。
  • 返回值: 三目运算符总是有一个返回值,因此可以嵌套使用或者用作函数的返回值。
  • 可读性: 尽管它很常用,但在复杂的逻辑判断中,使用过多的三目运算符可能会降低代码的可读性。

其他语言中的三目运算符

在其他编程语言中,三目运算符的使用方式基本类似,例如在 Python 中是 expr1 if condition else expr2,在 Java 和 JavaScript 中也是 condition ? expr1 : expr2
总结来说,三目运算符是一种灵活且常用的条件选择方式,可以简化代码并增强可读性,但应适度使用以保持代码清晰和易于维护。

单目运算符: ~ ++ – !

1.5赋值运算符

=+=-=*=/=%=
a-=5; //a=a-5;

1.6 运算符优先级

单算移关与异或逻条赋
单目运算符:~+±-!
算术运算符: /%±
移位运算符: <<>>
关系运算符: >>=<<===!=
位与运算符: &
异或运算符: ^
位或运算符: |
逻辑运算符: &&||
条件运算符: ?:
赋值运算符: =+=-=
=/=%=
image.png
解析让我们来计算表达式 (b >> 2) / (b >> 1) 的值,其中 b = 2

步骤分析:

  1. 位右移操作:
    • b >> 2 表示将变量 b 的二进制表示向右移动两位。
    • 对于 b = 2,其二进制表示是 00000010
    • b >> 2 向右移动两位后,得到 00000000,即十进制 0
  2. 计算 (b >> 2) / (b >> 1)
    • b >> 1 表示将 b 的二进制表示向右移动一位。
    • 对于 b = 2b >> 1 向右移动一位后,得到 00000001,即十进制 1
  3. 进行除法运算:
    • 现在我们有 (b >> 2) = 0(b >> 1) = 1
    • 所以,表达式 (b >> 2) / (b >> 1) 等价于 0 / 1
  4. 计算结果:
    • 0 / 1 的值为 0

结论:

因此,表达式 (b >> 2) / (b >> 1) 的值是 0,所以答案是 A. 0
image.png
解析让我们逐步分析这个表达式 c = a ^ b << 2; 并确定 c 的二进制值。
给定的变量初始化:

  • char a = 3; // 二进制表示为 00000011
  • int b = 6; // 二进制表示为 00000000 00000110
  • char c; // c 尚未初始化,我们将计算它的值。

步骤分析:

  1. 位左移操作 b << 2
    • b 是整数,b << 2 表示将 b 的二进制表示向左移动两位。
    • 对于 b = 6,其二进制表示是 00000000 00000110
    • b << 2 向左移动两位后,得到 00000000 00011000
  2. 按位异或操作 a ^ (b << 2)
    • a 的二进制表示是 00000011
    • (b << 2) 的结果是 00011000

然后执行按位异或操作: ```00000011 (a) ^ 00011000 (b << 2)

  • 00011011

结论:

根据以上计算,表达式 c = a ^ b << 2; 的计算结果是 00011011,即二进制形式。
因此,答案是 A. 00011011
image.png
解析

步骤分析:

  1. 变量初始化:
    • int x = 2;
    • int y = 3;
    • int z = 4;
  2. 计算 y > !z
    • !z 表示取 z 的逻辑非,因为 z 是非零的,所以 !z 的值为 0
    • 所以,表达式变为 y > 0,即 3 > 0
    • 因此,y > !z 的结果为真,也就是 1(在C语言中,真为1,假为0)。
  3. 计算 x + (y > !z)
    • x 的值是 2
    • (y > !z) 的值是 1
    • 所以,x + (y > !z) 变成了 2 + 1

结果:

因此,表达式 x + (y > !z) 的值为 3
答案是 3

标点符号

英文,;[ ]{}()…

分隔符

空格tab\n

[2]变量

程序运行过程中会发生变化
格式:
存储类型 数据类型 变量名
int a;
存储类型:决定变量存储位置
数据类型:决定变量开辟空间大小
变量名:遵循标识符命名规则

名字字节大小取值范围
int整型4-2,147,483,648 到 2,147,483,647
char字符型10 到 255 或 -128 到 127
short短整型2-32,768 到 32,767
long长整型8-2,147,483,648 到 2,147,483,647 或 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807,具体取决于平台。
float单精度浮点型4-3.4E+38 到 +3.4E+38
double双精度浮点型8-1.7E+308 到 +1.7E+308

printf(“%ld\n”,sizeof(long));

局部变量和全局变量的区别:

局部变量全局变量
定义位置函数体内部函数体外部
初值未初始化,值是随机值未初始化,值是0
存储位置栈区全局区
生命周期同当前函数体共存亡同整个程序共存亡
作用域当前函数体内部整个程序

局部变量和全局变量的区别局部变量(Local variables)和全局变量(Global variables)是编程中常见的概念,它们之间的主要区别如下:

  1. 作用域(Scope)
    • 局部变量的作用域仅限于定义它们的特定代码块(通常是函数内部)。出了这个代码块,局部变量就不再有效。
    • 全局变量的作用域则更广泛,它们定义在程序的任何地方(通常是在函数外部),整个程序都可以访问这些变量。
  2. 生存期(Lifetime)
    • 局部变量的生存期仅限于其所属的代码块执行期间。一旦代码块执行完毕,局部变量就会被销毁,释放其占用的内存。
    • 全局变量在程序开始运行时创建,在程序运行期间一直存在,直到程序结束或显式销毁。
  3. 访问权限
    • 局部变量通常只能被定义它们的代码块内部的语句访问和修改。
    • 全局变量可以在程序的任何地方被访问和修改。这也使得全局变量具有潜在的风险,因为任何函数都可以改变全局状态,导致程序的行为难以预测和调试。
  4. 命名冲突
    • 局部变量允许在不同的函数中使用相同的名称,因为它们的作用域是相互独立的。同样的名称可以在不同函数中分别使用而不会发生冲突。
    • 全局变量一般来说应当避免过多使用,因为它们的作用域过于广泛,可能会导致命名冲突和程序维护上的困难。

在实际编程中,为了避免副作用和不必要的复杂性,通常建议尽可能使用局部变量来限制变量的作用域,只有在确实需要在程序的多个地方共享状态时才使用全局变量。

[3]常量

程序运行过程中不会发生变化

程序运行过程中不会发生变化

3.1整型常量

八进制十进制十六进制

3.2字符常量

字符由’‘包裹一个字符
字符串由" "包裹,由’\0’作为字符串的结束标志
字符数组----》

3.3浮点型常量

floatdouble

3.4标识常量

宏定义:<br />格式:#define宏名		常量值或表达式或代码段<br />宏名:一般用大写表示,为了和普通变量区分开<br />注意:先原样替换,再计算
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值