c语言基础之运算符

赋值运算符

 赋值运算符为变量赋值,此语句将整数值分配给变量 。赋值操作始终从右到左进行,例如x = 4

算术运算符 ( +, -, *, /, % )

加法

 减法

乘法

除法

 模运算符,用百分号 () 表示,给出两个值的除法的余数

 复合赋值(+=、-=、*=、/=、%=、>>=、<<=、&=、^=、|=)

 复合赋值运算符通过对变量执行操作来修改变量的当前值。它们等效于将运算结果分配给第一个操作数

例如

y+= x 与 y = y + x,剩下以此类推

 递增和递减 (++, --)

 递增(++)和递减(--)运算符用于增加或减少变量的值。这两种运算符都有前缀和后缀形式,它们的主要区别在于操作的执行顺序和返回的值

有些表达式可以进一步缩短:增加运算符 () 和减少运算符 () 将存储在变量中的值增加或减少 1

在功能上都是等效的;它们中的三个将 x的值增加 1
++x;
x+=1;
x=x+1;


在功能上都是等效的;它们中的三个将 的值增加 1

  1. 前缀形式:

    • ++variable:前缀递增运算符会先增加变量的值,然后再使用新的值进行计算。
    • --variable:前缀递减运算符会先减少变量的值,然后再使用新的值进行计算。
  2. 后缀形式:

    • variable++:后缀递增运算符会先使用变量的当前值进行计算,然后才增加变量的值。
    • variable--:后缀递减运算符会先使用变量的当前值进行计算,然后才减少变量的值。

示例代码:

#include <stdio.h>
int main()
{
    int a = 8 ;
    // 后缀递增
    int b = a++;
    //前缀递增
    int c = ++a;
    //后缀递减
    int d = a--;
    //前缀递减
    int f = --a;
    printf("%d\n", b);
    printf("%d\n", c);
    printf("%d\n", d);
    printf("%d\n", f);
    return 0;
}
    
 

 关系运算符和比较运算符 ( ==, !=, >, <, >=, <= )

 可以使用关系运算符和相等运算符比较两个表达式。例如,要知道两个值是否相等,或者一个值是否大于另一个值。此类操作的结果为 true 或 false(即布尔值

算子描述
==等于
!=不等于
<小于
>大于
<=小于或等于
>=大于或等于

 例子:

(5 == 5)     //  true
(5 > 4)      //  true
(8 != 9)     //  true
(10 >= 10)     // true
(7 < 3)      //  false 
  •  可以比较的不仅仅是数值常量,而是任何值,当然也包括变量

 逻辑运算符 ( !, &&, | |)

逻辑非 (!)

一个表达式的值进行否定,如果它的操作数是 ,如果它的操作数是 。基本上,它返回计算其操作数的相反布尔值。其中0 代表假,非0 代表真

示例代码:

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 0;

    // 逻辑非
    int c = !a; // c 的值为 0,因为 a 非零,所以 !a 为假
    printf("%d\n",c);
    return 0;
}
    

 

逻辑与 (&&)

  • 对两个表达式进行逻辑与操作。
  • 如果两个表达式的值都为非0(真),则 && 运算后的结果为1(真)。
  • 否则,如果任意一个表达式的值为0(假),则整个 && 运算的结果为0(假)
  • 以下面板显示了运算符计算表达式的结果
&& OPERATOR(和)
aba && b
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefase

短路行为:当左侧表达式的值为0(假)时,由于无论右侧表达式的值如何,整个 && 运算的结果都已经确定为0(假),所以编译器可能会优化代码,不再评估右侧的表达式

逻辑或 (||)

  • 对两个表达式进行逻辑或操作。
  • 如果两个表达式中任意一个的值为非0(真),则 || 运算后的结果为1(真)。
  • 否则,如果两个表达式的值都为0(假),则整个 || 运算的结果为0(假)

||运算符(或)
aba || b
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse
  • 短路行为:当左侧表达式的值为非0(真)时,由于无论右侧表达式的值如何,整个 || 运算的结果都已经确定为1(真),所以编译器可能会优化代码,不再评估右侧的表达式。

 条件三元运算符 ( ? )

 条件运算符计算表达式,如果该表达式的计算结果为 ,则返回一个值,如果表达式的计算结果为 ,则返回另一个值

基本语法:condition ? value_if_true : value_if_false;

示例代码:

#include <stdio.h>
int main()
{
    int a, b, c;

    a = 2;
    b = 7;
    c = (a > b) ? a : b;

    printf("%d\n", c);

    

}
    

注意:在实际编程中,为了提高可读性,对于多个条件的情况,通常会使用 if-else 语句而不是连续的三元运算符

 逗号运算符 ( , )

  逗号运算符 () 用于分隔两个或多个表达式,这些表达式仅应包含一个表达式。当必须计算表达式集的值时,仅考虑最右边的表达式

 例如a = (b=3, b+2);

 按位运算符 ( &, |, ^, ~, <<, >> )

 按位运算符修改变量时,会考虑表示它们存储的值的位模式。

算子ASM 等效项描述
&AND按位 AND
|OR按位包含 OR
^XOR按位独占 OR
~NOT一元补码(位反转)
<<SHL向左移动位
>>SHR向右移动位

 显式类型转换运算符

在C++中,有四种显式类型转换运算符用于执行特定类型的强制转换:

  1. static_cast

    • 用于在编译时可确定的类型之间进行转换,如基本数据类型(int、float、double等)之间的转换,或指针类型和引用类型之间的转换。
    • 可以用于非多态类型的转换,但如果尝试向下转换一个基类指针或引用到不相关的派生类,结果是未定义的。
    • 示例:int i = 10; float f = static_cast<float>(i);
  2. dynamic_cast

    • 主要用于运行时的类型检查和转换,特别是对于多态类型(包含虚函数的类)的转换。
    • 当试图将基类指针或引用转换为派生类时,如果实际对象不是目标类型或者是指向null的指针,dynamic_cast会返回nullptr(对于指针)或抛出bad_cast异常(对于引用)。
    • 示例:Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
  3. const_cast

    • 用于修改类型的const、volatile或__unaligned属性,但不能改变对象的实际类型。
    • 主要用于去除const限制,以便对原本为const的对象进行修改。但是,如果对象实际上是常量或者被定义为const,那么试图修改其内容会导致未定义的行为。
    • 示例:const int ci = 10; int& i = const_cast<int&>(ci); // 尽管去除了const,但修改i仍然是未定义行为
  4. reinterpret_cast

    • 用于底层的比特模式转换,通常用于不同类型之间的转换,如将指针转换为整数或反过来转换。
    • 这种转换非常危险,因为它们忽视了类型的安全性,可能导致未定义的行为或数据损坏。
    • 示例:int* ip = reinterpret_cast<int*>(some_char_ptr); // 风险操作,将字符指针转换为整数指针

 

 sizeof

  此运算符接受一个参数,该参数可以是类型或变量,并返回该类型或对象的大小(以字节为单位)

x = sizeof (char);这里,被赋值 ,因为是一个大小为一个字节的类型。返回的值是编译时常量,因此它始终在程序执行之前确定

1.计算基本数据类型的大小

示例代码:

#include <stdio.h>
int main()
{
    int a;
    printf("Size of int: %zu bytes\n", sizeof(int)); 
}

2.计算变量的大小:

示例代码:

#include <stdio.h>
int main()
{
    double c;
    printf("Size of double variable 'c': %zu bytes\n", sizeof(c)); 
  
}
    

3.计算数组的大小(注意:结果是整个数组的大小,而不是元素的数量):

示例代码:

#include <stdio.h>
int main()
{
    int array[10];
    printf("Size of int array 'array': %zu bytes\n", sizeof(array));

}

4.计算结构体或类的大小:

示例代码:

#include <stdio.h>
int main()
{
    struct MyStruct {
        int a;
        char b;
        double c;
    };

    MyStruct myStruct;
    printf("Size of MyStruct: %zu bytes\n", sizeof(myStruct));
   
}

注意的是,sizeof 不会计算动态分配内存的大小,例如通过 mallocnew 分配的内存。此外,对于指针变量,sizeof 返回的是指针本身的大小,而不是指针所指向的数据的大小

 运算符的优先级

水平优先级组算子描述分组
1范围::范围限定符从左到右
2后缀(一元)++ --后缀递增/递减从左到右
()功能形式
[]下标
. ->会员访问
3前缀(一元)++ --前缀递增/递减从右到左
~ !按位 NOT / 逻辑 NOT
+ -一元前缀
& *引用/取消引用
new delete分配/取消分配
sizeof参数包
(type)C型铸造
4指向成员的指针.* ->*访问指针从左到右
5算术:缩放* / %乘法、除法、取模从左到右
6算术:加法+ -加法、减法从左到右
7按位移位<< >>左移,右移从左到右
8关系< > <= >=比较运算符从左到右
9平等== !=平等/不平等从左到右
10&按位 AND从左到右
11排他性或^按位异或从左到右
12包含或|按位 OR从左到右
13连接&&logical 和从左到右
14分离||逻辑 OR从左到右
15赋值级表达式= *= /= %= += -=
>>= <<= &= ^= |=
赋值/复合赋值从右到左
?:条件运算符
16测 序,逗号分隔符从左到右
  • 38
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值