c语言入门——操作符

目录

一.分类

二.操作符

1.算术操作符

2.移位操作符

(1).>>

(2).<<

(3).注意

(4).应用

3.位操作符

(1).使用

(2).应用

4.赋值操作符

5.单目操作符

(1).逻辑反操作

(1).sizeof与数组

(2).~

(3).++  --

(4).强制类型转换

6.关系操作符

7.逻辑操作符

8.条件操作符(三目操作符)

9.逗号表达式

10.下标引用操作符

11.函数调用操作符

12.结构成员


一.分类

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号表达式

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



二.操作符

1.算术操作符

+     -    *    /    %

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

2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。

3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。


2.移位操作符

>>    <<

进行移位操作的应该为整数的二进制补码

(1).>>

(1).算数右移:最右一位去除,符号位补为原符号位(通常)

(2).逻辑右移:最右一位去除,符号位补0

(2).<<

左边去除,右边补0

(3).注意

对于移位运算符,不要移动负数位,这个是标准未定义的。

num >> -1   //error

(4).应用

当我们要求一个数的二进制表示中1的个数,我们可以使用移位操作符和位操作符(就在下面有讲)

想要统计二级制中1的个数,我们可以用各位的1来与这个数按位与来判断该位是否为1

而想要的到每一位的1,我们可以利用循环和移位

整体代码如下所示

#include 
int main()
{
    int num = -1;
    int i = 0;
    int count = 0;
    for(i=0; i<32; i++)
    {
        if( num & (1 << i) )
        count++; 
    }
    printf("二进制中1的个数 = %d\n",count);
    return 0;
}

3.位操作符

进行操作的也是二进制补码

&按位与       两个数的相应位均为1时结果位为1

| 按位或       两个数的相应位均为0时结果位为0

^按位异或    两个数的相应位相同时结果位为0,相异为1

(1).使用

例如 int a=5,b=3;

将两个数转化为二进制

a:00000000 00000000 00000000 00000101

b:00000000 00000000 00000000 00000011

若c=a&b

c:00000000 00000000 00000000 00000001

(2).应用

当我们要进行两个数的交换时,我们首先会想到创建临时变量来解决

那么如何不使用临时变量来解决这个问题?

我们首先可以想到使用加减法来解决

a=a+b;
b=a-b;
a=a-b;

这的确是一种思路,然而当a+b的结果超出a,b的取值范围时,这种方法便会出现问题

我们还可以使用位操作符来解决这个问题

a=a^b;
b=a^b;
a=a^b;

(1).当a=a^b时,a的二进制中的1表示两数该位原本不同,0表示相同

例如a=5,b=3

转换为二进制为

a:00000000 00000000 00000000 00000101

b:00000000 00000000 00000000 00000011

a=a^b后

a:00000000 00000000 00000000 00000110

(2).当b=a^b时

b:00000000 00000000 00000000 00000101

可以看到,b已经等于原本a的值

(3).当a=a^b时

a:00000000 00000000 00000000 00000011

如此,便完成了a与b的交换

而这种办法,由于按位异或是对二进制进行操作,所以不会发生超出范围的问题


4.赋值操作符

(1).=

(2).赋值操作符可以连续使用

(3).复合赋值符

+=   -=   *=   /=   %=   >>=   <<=   &=   |=   ^=


5.单目操作符

!           逻辑反操作

-           负值

+           正值(可以忽略)

&           取地址

sizeof      操作数的类型长度(以字节为单位)

~           对一个数的二进制按位取反

--          前置、后置--

++          前置、后置++

*           间接访问操作符(解引用操作符)

(类型)       强制类型转换

这些单目操作符,其实有很多我们经常使用到,例如 -  +  &  *,这里就不做赘述。

(1).逻辑反操作

在if(flag)中,判断条件为flag为真

当为if(!flag)时,判断条件为flag为假

布尔类型

布尔类型就是用来表示真假的类型

stdbool.h

_Bool(bool) flag=true(false)

自定义函数的返回值也可以为布尔类型,但注意返回值只能为true/false

(1).sizeof与数组

 (1).若操作数为表达式,不进行实际运算

(2).sizeof后的括号可以省略

(3).

#include 

void test1(int arr[])
{
    printf("%d\n", sizeof(arr));
}

void test2(char ch[])
{
    printf("%d\n", sizeof(ch));
}

int main()
{
    int arr[10] = {0};
    char ch[10] = {0};
    printf("%d\n", sizeof(arr));
    printf("%d\n", sizeof(ch));
    test1(arr);
    test2(ch);
    return 0;
}

以上代码所打印的应为40 10 4 4

由于int类型数据占4个字节,char类型数据占1个字节,所以前两个为40,10,这很好理解

而当传参后,sizeof的操作数arr ch都变为了指针类型,所以在x64中都为4

(2).~

按位取反(包括符号位)

(3).++  --

(1).前置先运算再赋值,后置先赋值再运算

(2).++ --不要乱用,例如b=a++会对a做出改变,而b=a+1不会

(3).指针也可以使用

(4).强制类型转换

尽量避免强制类型转换


6.关系操作符

>   >=   <   <=   !=    ==  


7.逻辑操作符

&&     逻辑与

||        逻辑或

在if语句中我们已经使用过这两个操作符

1.&&——两侧都为真时返回1,否则返回0

   从左向右判断,左侧为假,右侧不进行运算

2.||——两侧都为假时返回0,否则返回1

   从左向右判断,左侧为真,右侧不进行运算


8.条件操作符(三目操作符)

exp1 ? exp2 : exp3

当exp1成立时执行exp2,否则执行exp3

例如

b=(a>5 ? 3 : -3);

等同于

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

9.逗号表达式

逗号表达式,就是用逗号隔开的多个表达式。

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

例如

int a=1;
int b=2;
int c=(a>b , a=b+10 , a , b=a+1);
//a=12  b=13  c=13

在了解到逗号表达式后,我们可以对一些代码进行优化

a = get_ _va1();
count_ va1(a);
while (a > 0)
{
    //业务处理
    a = get_ _va1();
    count_ val(a) ;
}

如果使用逗号表达式,改写:

while (a = get_ _va1(), count_ val(a),a>0)
{
    //业务处理
}

但一定要思考清楚使用逗号表达式是否恰当


10.下标引用操作符

[ ] 下标引用操作符

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

例如int arr[10]={ 0 }

那么 arr[9] 中 arr 和 9 便是操作数。


11.函数调用操作符

( ) 函数调用操作符

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

当函数没有参数时,该操作符的操作数最少,为1。


12.结构成员

(1).内置类型——char、int.....

     自定义类型(聚合类型)——结构体、枚举、联合体

(2).结构体

在描述某些对象时,不能简单地使用单个内置类型,可以选择结构体来进行描述

以一本书为例,要有名字、价格等

struct Book//类型
{
    char name[10];
    int price;
};

int main()
{
    struct Book b1={"书名",10};
    return 0;
}

而当我们要使用结构体中的结构成员时,有以下两种方法

. 结构体.成员名

-> 结构体指针->成员名

例如我们要打印结构成员时

printf("%d\n",b1.price)

而和其他数据一样,当进行传参时,传值操作也会导致无法改变原数据

所以要使用结构体指针

void print1(struct Book* p)
{
    printf("%s %s %d\n", (*p).name, (*p). author, (*p). price);
    printf("%s %s %d\n",p->name, p->author, p->price);
}

我们可以采用常规的解引用操作符,也可以使用我们上面说到的->操作符


表达式求值

累了,不写了,下一篇再说

你可能感兴趣的:(c语言入门,c语言,学习)