C语言-操作符详解

本文详细介绍了C语言中的各种操作符,包括算术、移位、位、赋值、单目、关系、逻辑、条件、逗号等,并讨论了表达式求值、隐式类型转换和算术转换的规则,是深入理解C语言操作符的宝贵资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

操作符

算术操作符

移位操作符

左移操作符

右移操作符

位操作符

赋值操作符

单目操作符

 sizeof运算符

关系操作符

逻辑操作符

条件操作符

逗号表达式

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

[ ] 下标引用操作符

 ( ) 函数调用操作符

 访问结构的成员操作符

 表达式求值

 隐式类型转换

 整型提升

 如何进行整体提升呢?

算术转换 


操作符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的操作符。

算术操作符

+     -    *     /     %

#include <stdio.h>
 
int main()
{
   int a = 21;
   int b = 10;
   int c ;
 
   c = a + b;
   printf("Line 1 - c 的值是 %d\n", c );
   c = a - b;
   printf("Line 2 - c 的值是 %d\n", c );
   c = a * b;
   printf("Line 3 - c 的值是 %d\n", c );
   c = a / b;
   printf("Line 4 - c 的值是 %d\n", c );
   c = a % b;
   printf("Line 5 - c 的值是 %d\n", c );

 1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。

2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

移位操作符

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

左移操作符

移位规则: 左边抛弃、右边补0

右移操作符

移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用 0 填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃
注意:对于移位运算符,不要移动负数位,这个是标准未定义的。

位操作符

& // 按位与
| // 按位或
^ // 按位异或
注:他们的操作数必须是整数。

 例子:

#include <stdio.h>
int main()
{
 int num1 = 1;
 int num2 = 2;
 num1 & num2;
 num1 | num2;
 num1 ^ num2;
 return 0; }

 不能创建临时变量(第三个变量),实现两个数的交换。

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

赋值操作符

运算符描述实例
=简单的赋值运算符,把右边操作数的值赋给左边操作数C = A + B 将把 A + B 的值赋给 C
+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C += A 相当于 C = C + A
-=减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数C -= A 相当于 C = C - A
*=乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数C *= A 相当于 C = C * A
/=除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数C /= A 相当于 C = C / A
%=求模且赋值运算符,求两个操作数的模赋值给左边操作数C %= A 相当于 C = C % A
<<=左移且赋值运算符C <<= 2 等同于 C = C << 2
>>=右移且赋值运算符C >>= 2 等同于 C = C >> 2
&=按位与且赋值运算符C &= 2 等同于 C = C & 2
^=按位异或且赋值运算符C ^= 2 等同于 C = C ^ 2
|=按位或且赋值运算符C |= 2 等同于 C = C | 2

例子:

#include <stdio.h>

main()
{
   int a = 21;
   int c ;

   c =  a;
   printf("Line 1 - =  运算符实例,c 的值 = %d\n", c );

   c +=  a;
   printf("Line 2 - += 运算符实例,c 的值 = %d\n", c );

   c -=  a;
   printf("Line 3 - -= 运算符实例,c 的值 = %d\n", c );

   c *=  a;
   printf("Line 4 - *= 运算符实例,c 的值 = %d\n", c );

   c /=  a;
   printf("Line 5 - /= 运算符实例,c 的值 = %d\n", c );

   c  = 200;
   c %=  a;
   printf("Line 6 - %= 运算符实例,c 的值 = %d\n", c );

   c <<=  2;
   printf("Line 7 - <<= 运算符实例,c 的值 = %d\n", c );

   c >>=  2;
   printf("Line 8 - >>= 运算符实例,c 的值 = %d\n", c );

   c &=  2;
   printf("Line 9 - &= 运算符实例,c 的值 = %d\n", c );

   c ^=  2;
   printf("Line 10 - ^= 运算符实例,c 的值 = %d\n", c );

   c |=  2;
   printf("Line 11 - |= 运算符实例,c 的值 = %d\n", c );

}

单目操作符

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

 

 sizeof运算符

sizeof是C语言的关键字,它用来计算变量(或数据类型)在当前系统中占用内存的字节数。

sizeof不是函数,产生这样的疑问是因为sizeof的书写确实有点像函数,sizeof有两种写法:

用于数据类型:

sizeof(数据类型);


printf("字符型变量占用的内存是=%d\n",sizeof(char)); 
  // 输出:字符型变量占用的内存是=1 

printf("整型变量占用的内存是=%d\n",sizeof(int)); 
  // 输出:整型变量占用的内存是=4

数据类型必须用括号括住。 

用于变量

sizeof(变量名);
sizeof 变量名;

int ii;
  printf("ii占用的内存是=%d\n",sizeof(ii)); 
  // 输出:ii占用的内存是=4

  printf("ii占用的内存是=%d\n",sizeof ii); 
  // 输出:ii占用的内存是=4

关系操作符

>
>=
<
<=
!=   用于测试 不相等
==       用于测试 相等
注意:在编程过程中,== 和 = 不要写错了

逻辑操作符

&&     逻辑与        如果两个操作数都非零,则条件为真。
||           逻辑或        如果两个操作数中有任意一个非零,则条件为真。

条件操作符

exp1 ? exp2 : exp3

 举个例子:

if (a > 5)
        b = 3;
else
        b = -3;

//将上述代码转换成表达式

a > 5 ? 3 : -3;

逗号表达式

exp1, exp2, exp3, …expN

逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

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

[ ] 下标引用操作符

操作数:一个数组名 + 一个索引值

int arr[10];//创建数组
 arr[9] = 10;//实用下标引用操作符。
 [ ]的两个操作数是arr和9。

 ( ) 函数调用操作符

接收一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

#include <stdio.h>
 void test1()
 {
 printf("hehe\n");
 }
 void test2(const char *str)
 {
 printf("%s\n", str);
 }
 int main()
 {
 test1();            //实用()作为函数调用操作符。
 test2("hello bit.");//实用()作为函数调用操作符。
 return 0;
 }

 访问结构的成员操作符

.          结构体. 成员名
->          结构体指针-> 成员名
#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; }

 表达式求值

 表达式求值的顺序一部分是由操作符的优先级和结合性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。

 隐式类型转换

C 的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为 整型 提升

 整型提升

表达式的整型运算要在 CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的字节长度
一般就是 int 的字节长度,同时也是 CPU 的通用寄存器的长度。
因此,即使两个 char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长
度。
通用 CPU general-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

算术转换 

 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。

 

### 解决PyCharm无法加载Conda虚拟环境的方法 #### 配置设置 为了使 PyCharm 能够成功识别并使用 Conda 创建的虚拟环境,需确保 Anaconda 的路径已正确添加至系统的环境变量中[^1]。这一步骤至关重要,因为只有当 Python 解释器及其关联工具被加入 PATH 后,IDE 才能顺利找到它们。 对于 Windows 用户而言,在安装 Anaconda 时,默认情况下会询问是否将它添加到系统路径里;如果当时选择了否,则现在应该手动完成此操作。具体做法是在“高级系统设置”的“环境变量”选项内编辑 `Path` 变量,追加 Anaconda 安装目录下的 Scripts 文件夹位置。 另外,建议每次新建项目前都通过命令行先激活目标 conda env: ```bash conda activate myenvname ``` 接着再启动 IDE 进入工作区,这样有助于减少兼容性方面的问题发生概率。 #### 常见错误及修复方法 ##### 错误一:未发现任何解释器 症状表现为打开 PyCharm 新建工程向导页面找不到由 Conda 构建出来的 interpreter 列表项。此时应前往 Preferences/Settings -> Project:...->Python Interpreter 下方点击齿轮图标选择 Add...按钮来指定自定义的位置。按照提示浏览定位到对应版本 python.exe 的绝对地址即可解决问题。 ##### 错误二:权限不足导致 DLL 加载失败 有时即使指定了正确的解释器路径,仍可能遇到由于缺乏适当的操作系统级许可而引发的功能缺失现象。特别是涉及到调用某些特定类型的动态链接库 (Dynamic Link Library, .dll) 时尤为明显。因此拥有管理员身份执行相关动作显得尤为重要——无论是从终端还是图形界面触发创建新 venv 流程均如此处理能够有效规避此类隐患。 ##### 错误三:网络连接异常引起依赖下载超时 部分开发者反馈过因网速慢或者其他因素造成 pip install 操作中途断开进而影响整个项目的初始化进度条卡住的情况。对此可尝试调整镜像源加速获取速度或是离线模式预先准备好所需资源包后再继续后续步骤。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值