操作符和表达式

(1)算术操作符

+  -  *  /  %

除了%操作符外,其他算术操作符可以作用于整形和浮点数;

对于/操作符,如果两个操作数都为整数,执行整数除法。操作数只要有浮点数,执行浮点数除法;

%操作符的两个操作数必须是整数,返回的是整除后的余数。

(2)移位操作符

<<左移操作数   

>>右移操作数

a.左移操作符

移位规则:向左移一位,右边补0;

int num = 7;     

num  << 1;

00000000 00000000 00000000 000000111(num的二进制)

00000000 00000000 00000000 000001110(num左移一位的结果)

b.右移操作符

移位规则:

    逻辑移位:左边用0填充,右边丢弃。

    算术移位:左边用该原值的符号位填充,右边丢弃。

int num = -1;

num >> 1;

11111111 11111111 11111111 11111111(num的二进制)

01111111 11111111 11111111 11111111(num逻辑移位的结果)

11111111 11111111 11111111 11111111(num算术移位的结果)

注意:对于移位操作符,不要移动负数位。

int num = 10;

num >> -1;  //error

(3)位操作符

位操作符有:
 
& 按位与
 | 按位或
^ 按位异或

他们的操作数必须是整数。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int num1 = 1;
    int num2 = 2;
    printf("num1 & num2 = %d\n", num1 & num2);
    printf("num1 | num2 = %d\n", num1 | num2);
    printf("num1 ^ num2 = %d\n", num1 ^ num2);
    system("pause");
    return 0;
}
//num1 & num2 = 0
//num1 | num2 = 3
//num1 ^ num2 = 3

求平均数

average=(m&n)+((m^n)>>1);
//相同的加,不同的加

(4)赋值操作符

使用赋值操作符赋值
 
int i = 122;
i = 23;
int x = i = i+11;

复合赋值操作符

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

(5)单目操作符

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

a.sizeof用法

#include <stdio.h> 
#include<stdlib.h>
int main()
{
     int a = -10;
     int *p = NULL;
     printf("%d\n", !2);
     printf("%d\n", !0);
     a = -a;
     p = &a;
     printf("%d\n", sizeof(a));
     printf("%d\n", sizeof(int));
     printf("%d\n", sizeof a);//说明sizeof不是函数
    printf("%d\n", sizeof int);//出错。加类型必须有括号
     system("pause");
     return 0;
}
//输出:
//0
//1
//4
//4
//4
#include<stdio.h>
int main()
{
     int a = 20;
     short b = 3;
     printf("%d\n", sizeof(b = a + 1));
     printf("%d\n", b);
     system("pause");
     return 0;
}
//输出:2 3 
//放在sizeof内部中的表达式不参与运算
#include <stdio.h> 
#include<stdlib.h>
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); //传的是数组首元素地址,即一个指针,大小为4字节
     test2(ch);//传过去的是指针
     system("pause");
     return 0;
}
输出:40   10    4    4

b.~的应用

将15的二进制码倒数第三位取反:

00000000 00000000 00000000 00001111(反码)

11111111 11111111 11111111 11111011(&这个数字b得到所求结果)

00000000 00000000 00000000 00000100(该数字按位取反得到数字b)(该数字表达为1<<2)

c. 前置++(—)与后置++(—)的区别

#include<stdio.h>
int main()
{
    int a = 1;
    int b = a++;
    printf("%d\n", b);//1
    printf("%d\n", a);//2
    return 0;
}

后置++先使用后作用表达式。

#include <stdio.h> 
#include<stdlib.h>
int main()
{
     int a = 3;
     int b = (++a) + (++a) + (++a); //这种表达式不对。
     printf("%d\n", b);
     system("pause");
     return 0;
}
//在VS2013中输出:18

d.间接访问操作符

#include<stdio.h>
int main()
{
    int num = 10;
    int *p = &num;
    printf("%d\n", *p);
    return 0;
}
//输出:10

(6)关系操作符

>
>=
<
<=
!=
== 

(7)逻辑操作符

&&逻辑与
||逻辑或
#include<stdio.h>
#include<stdlib.h>
int main() 
{
     int i = 0, j = 0, a = 0, b = 2, c = 3, d = 4;
     i = a++&&++b&&d++;       //1 2 3 4
     //j = a++||++b||d++;     //1 3 3 4
     printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d); 
     system("pause");
     return 0;
}

(8)条件操作符

表达式1?表达式2:表达式3

(9)逗号表达式

表达式1,表达式2,表达式3,…,表达式n

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

(10)下标引用操作符[ ]

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

#include<stdio.h>
#include<stdlib.h>
int main() 
{
     int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     printf("%p\n", &arr[4]);
     printf("%p\n", arr + 4);
     printf("%d\n", *(arr+4));
     printf("%d\n", *(4 + arr));
     printf("%d\n", arr[4]);
     printf("%d\n", 4[arr]);
     system("pause");
     return 0;
}
//输出:
//012FFD0C
//012FFD0C
//5
//5
//5
//5

(11)函数调用操作符

函数调用操作符,接受一个或多个操作数,第一个操作数是函数名(地址),剩余的是传给函数的参数。

(12)结构成员访问操作符

.结构体.成员名

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

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{
     char name[20];
     int age;
     char sex[5];
};
int main() 
{
     struct Stu s;
     struct Stu *p = &s;

     strcpy(s.name, "刘明");//将“刘明”放到name空间里
     s.age = 19;
     strcpy(s.sex, "男");

     strcpy((*p).name, "小强");
     (*p).age = 20;
     strcpy((*p).sex, "男");

     strcpy(p->name, "晓花");
     p->age = 20;
     strcpy(p->sex, "女");

     system("pause");
     return 0;
}

(13)表达式求值

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

a.整形提升

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

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
     char a = 2;
     char b = 127;
     char c = a + b;
     printf("%d\n", c);
     system("pause");
     return 0;
}
//输出:129
//a:00000010
//b:01111111
//整型提升:
//00000000 00000000 00000000 00000010—--a
//00000000 00000000 00000000 01111111—--b
//00000000 00000000 00000000 10000001---a+b
//10000001——-c(c的类型为char型,带符号位)
//11111111 11111111 11111111 10000001——c(高位补符号位)
//数据以补码方式存储,c为-127.

b.算术转换

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

寻常算术转换:

long double
double
float
unsigned long int
long int
unsigned int 
int 

如果某个操作数的类型在上米娜列表中排名较低,那么首先要转换成另外一个操作数的类型后执行运算。

c.操作符的属性

    两个相邻的操作符,先执行优先级高的。若优先级相同,则取决于他们的结合性。

操作符优先级:

                                                                                                选自《C和指针》

#include<stdio.h>
int main()
{
    int i = 0;
    int tmp = (++i)+(++i)+(++i);
    printf("%d\n", tmp);
    return 0;
}
//输出12或10,没有唯一的计算路径

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值