+、-、*、/、%
注:(1)%取模操作符的两个操作数必须为整数;
(2)对于/操作符,如果两个操作数都为整数,则执行整数除法;如果有一个操作数为浮点数,则执行浮点数除法;
(3)除%操作符外,其他算术操作符都可以为任意数据类型。
2.移位操作符
<<、>>
(1)<<左移操作符
移位规则:左边抛弃、右边补0。
如:int a=10; //a=10在内存中以补码的形式存储,00000000 00000000 00000000 00001010;
int b=a<<1; //a左移一位后赋值给b,b在内存中的存储方式为:00000000 00000000 00000000 00010100,可知b=20;
注:a要左移一位,其实是以补码的形式存储在内存中的二进制数左移一位;左移操作,不会对被移对象造成影响。
(2)>>右移操作符
移位规则:(1)算术移位:左边补符号位,右边抛弃;
(2)逻辑移位:左边补0,右边抛弃。
如:int a=-1; //a=-1在内存中的二进制数为:11111111 11111111 11111111 11111111;
int b=a>>1; //a进行右移一位后赋值给b,b在内存中的二进制数为:11111111 11111111 11111111 11111111,b=-1;
3.位操作符
&、|、^
注:它们的操作数都必须是整数。
练习一下,&操作如下:
#include<stdio.h>
int main()
{
int a=3; //a在内存中的二进制数为:00000000 00000000 00000000 00000011;
int b=5; //b在内存中的二进制数为:00000000 00000000 00000000 00000101;
printf("%d\n",a&b); //a&b后在内存中的二进制数为:00000000 00000000 00000000 00000001,则a&b=1;
return 0;
}
//则|、^操作符同理。
4.赋值操作符
=
复合赋值符有:+=、-=、*=、/=、%=、>>=、<<=、&=、|=、^=
5.单目操作符
!、-、+、&、sizeof、~、--、++、*、(类型)
(1)!逻辑反操作
如:#include<stdio.h>
int main()
{
int flag=2;
printf("%d",flag); //输出的结果为2;
printf("%d",!flag); //输出的结果为0;
return 0;
}
(2)&取地址操作符
如数组取地址:#include<stdio.h>
int main()
{
int arr[10]={0};
printf("%p\n",&arr);
printf("%p\n",&arr);
printf("%p\n",arr);
printf("%p\n",arr+1);
return 0;
}
(3)sizeof操作符
目的:求操作数的类型长度,以字节为单位。
使用sizeof操作符时,需要注意以下三点:
第一点,sizeof不是函数,如:
#include<stdio.h>
int main()
{
int a=10;
printf("%d\n",sizeof(a)); //也可以写为printf("%d\n",sizeof a);说明sizeof不是函数;
printf("%d\n",sizeof(int)); //不可以写为printf("%d\n",sizeof int);这是错误的写法;
return 0;
}
第二点,sizeof内的表达式不执行,如:
#include<stdio.h>
int main()
{
short s=3;int a=20;
printf("%d\n",sizeof(s=a+1)); //该语句并没有给s进行赋值操作,输出结果仍然为short型的字节大小,即为2;
printf("%d\n",a); //a=20;
printf("%d\n",s); //s=3;
return 0;
}
第三点,对数组操作,如:
#include<stdio.h>
int main()
{
int arr[10]={0};printf("%d\n",sizeof(arr)); //该语句表示求arr这个数组的长度,即为40;
printf("%d\n",sizeof(arr+0)); //一旦对arr进行了运算操作,则arr表示的是首元素的地址,故输出为:4;
return 0;
}
需要注意:&数组名,表示该数组的地址;sizeof(数组名),该数组名表示整个数组,求的是整个数组的大小;除了这两个以外,遇到的所有的数组名均表示数组首元素的地址。
(4)--、++(前置、后置)
操作如下:
#include<stdio.h>
int main()
{
int i=3;int j=20;
printf("%d\n",i++); //先打印再修改i的值,即输出3;
printf("%d\n",++j); //先修改再打印j的值,即输出21;
return 0;
}
下面举一个特殊的例子:
#include<stdio.h>
int main()
{
int i=1;int ret=(++i)+(++i)+(++i);
printf("%d\n",ret); //在VS2008中输出12,在VC6.0中输出10;结果出现了不同,具体原因需实践操作来验证;
return 0;
}
(5)~按位取反操作符
#include<stdio.h>
int main()
{
int i=0; //0在内存中的二进制数为:00000000 00000000 00000000 00000000;printf("%d\n",~i); //取反后,二进制数为:11111111 11111111 11111111 11111111=-1;
return 0;
} // 故屏幕打印的结果为:-1;
(6) *(间接访问操作符/解引用操作符)
对象:只能对指针变量进行解引用。
(7)(类型)强制类型转换
如:#include<stdio.h>
int main( )
{
float f=3.14;
int a=(int)f; //强制类型转换,将float型转换为int型
printf("%d\n",a); //结果为:3
return 0;
}
6.关系操作符
>、>=、<、<=、==、!=
7.逻辑操作符
&&、||
举个例子:
#include<stdio.h>
int main( )
{
int a=1;
int b=2;
a&b; //结果为:0
a&&b; //结果为:1
a|b; //结果为:3
a||b; //结果为:1
return 0;
}
练习一下:
#include<stdio.h>
int main( )
{
int i=0,j=0,a=0,b=2,c=3,d=4;
i=a++&&++b&&d++;
printf("%d%d%d%d",a,b,c,d);
return 0;
}
结果为:1、2、3、4
注:&&、||出现时,都是先计算左边表达式的值,当左边表达式的值能确定整个表达式的值时,就不再计算右边表达式的值。
8.条件操作符(也称三目操作符)
?: //如exp1?exp2:exp3表示为如果exp1为真,则整个表达式的结果为exp2的结果;如果exp1为假,则整个表达式的结果为exp3的结果;
如:求两个数a、b的最大值max, int max=a>b?a:b;
9.逗号表达式
(exp1,exp2,……,expn) //表示从左到右依次执行,整个表达式的结果是最后一个表达式的结果;
举例说明:
#include<stdio.h>
int main( )
{
int a=0;
int b=1;
int c=2;
int d=(a>5,a=3,b=a+4,c=a-b); //执行过程:a>5,a=3,b=a+4=3+4=7,c=a-b=3-7=-4,此时将c赋给d,故得到d=-4;
int e=(a=3,b=a+4,c=a-b,a>5); //执行过程:a=3,b=a+4=3+4=7,c=a-b=3-7=-4,a>5,此时将a>5的结果赋给e,故e=0;
return 0;
}
10.下标引用操作符
[ ]
注:此操作符接收两个操作数,即为数组名、索引值。
举例说明:
#include<stdio.h>
int main( )
{
int arr[10]={0};
arr[4]=5; //此语句也可以写为*(arr+4)=5;或*(4+arr)=5;或4[arr]=5;
printf("%d",arr[4]);
return 0;
}
11.函数调用操作符
( )
注:(1)函数名( ),该函数名是该函数的地址;
(2)( )操作符至少有一个操作数,即函数名。
12.访问一个结构的成员
. //结构体.成员名
-> //结构体变量->成员名
(1)关于.的具体说明,举例如下:
#include<stdio.h>
#include<string.h>
Struct Stu //自定义结构体变量
{
short int age;
char name[10];
char sex[5];
int hight;
};
int main( )
{
Struct Stu s1; //创建该类型的结构体变量
strcpy(s1.name,"张三"); //通过strcpy( )函数对s1.name进行赋值;
return 0;
}
(2)关于->的具体说明,举例如下:
#include<stdio.h>
#include<string.h>
Struct Stu //自定义结构体变量
{
short int age;
char name[10];
char sex[5];
int hight;
};
int main( )
{
Struct Stu *p=&s1; //创建该类型的结构体指针变量
(*p).age=20;
p->age=20; //给p所指向的对象s1的age进行赋值;
strcpy((*p).name,"小强"); //通过strcpy( )函数对p所指向的对象s1的name进行赋值;
return 0;
}