1.操作符种类
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等
2. 算术操作符
+ - * / %
3.双目运算符两边的数值类型必须一致才能进行运算,如果不一致,系统先进行一致性转换。
转换规则:
char —>short —>int —>unsigned —>long —>double —>float
4.所有实数的运算都是以双精度方式进行的,若是单精度数值,则需要在尾数后面补0转换为双精度。
例:
#include <stdio.h>
int main()
{
int a = 8 ;
int b = 4 ;
int c = 0 ;
int d = 0 ;
c = a/b ; // 8/4=2; 8/2.0=4.0;
d = a%b ; // 8.0%2是错误的,%两端必须为整数;
return 0 ;
}
3. 移位操作符
#include <stdio.h>
int main()
{
int a = 1 ;//整型4个字节32位;0000 0000 0000 0000 0000 0001 (1)
int b = a << 1 ;//往左移一位:0000 0000 0000 0000 0000 0010 (2)
printf("b=%d\n",b);
return 0 ;
}
3.2 右移操作符
原码反码补码
正整数:原码反码补码相同;整数在内存中存储的是二进制的补码;
-1:
1000 0000 0000 0000 0000 0000 0000 01 (原码)
1111 1111 1111 1111 1111 1111 1111 10 (反码,符号位不用取反)
1111 1111 1111 1111 1111 1111 1111 11 (补码,反码+1)
4. 位操作符
#include <stdio.h>
int main()
{
int a = 1; // 0000 0000 0000 0001
int b = 2; // 0000 0000 0000 0010
int c = a & b; // 0000 0000 0000 0000 两个为1才为1
int d = a | b; // 0000 0000 0000 0011 有1个为1就为1
int e = a ^ b; // 0000 0000 0000 0011 两个为0就为0,两个为1也为0;
printf("c=%d d=%d e=%d ", c, d, e);
return 0;
}
5. 赋值操作符
一般形式:变量名 = 表达式
赋值运算符的优先级高于逗号运算符;注意= 与== 的区别;
赋值运算符的左侧只能是变量,而不能是常量或者表达式。右侧可以是表达式,包括赋值表达式;
规定最左边变量所得到的新值就是整个赋值表达式的值。
5.1复合赋值符
注:俩个符号之间不可以有空格,复合赋值符的优先级和赋值运算符相同。
int x = 2;
x = x+10; //与x += 10 是一样的。
x += 10;
//其他运算符一样的道理。这样写更加简洁
6. 单目操作符
6.1自加、 自减运算符
(1)作用:自加运算符“++”使运算变量的值增1,自减运算符“”使运算变量的值减1。
(2)均是单目运算符。运算对象可以是整型或实型变量,但不可以是常量和表达式。
(3)均可作为前缀运算符,也可作为后缀运算符构成一个表达式。++i, --i:在使用i之前,先使i的值加1或者减1,再使用此时的表达式的值参加运算。
i++,i--:在使用i之后,使i的值加1或者减1,再使用此时的表达式的值参加运算。
(4)结合方向:自右向左。
#include <stdio.h>
int main()
{
int a = 10;
int x = a++; //对a先使用,再增加,这样x的值是10;之后a变成11;
int b = ++a ; //a=11,先加再使用, 这样b的值为12; a变成的12 ;
int y = a--; //a=12,对a先使用,再自减,这样y的值是12;之后a变成11;
int c = --a; //a=11,先减再使用, 这样c的值为10, a变成10;
printf("a=%d x=%d b=%d y=%d c=%d ",a,x,b,y,c) ;
return 0;
}
6.2 sizeof 和 数组
#include <stdio.h>
void test1(int arr[])
{ // arr为数组首元素地址
printf("%d\n", sizeof(arr));//传过来的是地址32位平台为4个字节
} //64位平台为8个字节
void test2(char ch[])
{
printf("%d\n", sizeof(ch)); //ch为数组首元素地址
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr));//每个元素为int类型,一共10个元素;4乘10为40;
printf("%d\n", sizeof(ch));// 1乘10等于10;
test1(arr);
test2(ch);
return 0;
}
7. 关系操作符
8. 逻辑操作符
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++; //a++先使用再加,所以表达式为0,0与任何数都为0。
//当为0时,后面表达式系统就跳过了。
printf("a = %d b = %d c = %d d = %d", a, b, c, d); //1 2 3 4
return 0;
}
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++||++b||d++; //俩个有一个为1即为真(1),a++先使用再加,即表达式为0;
//为0继续算后面的(为真就不用算了),++b为3(真).
printf("a = %d b = %d c = %d d = %d", a, b, c, d); //i的值为1
return 0;
}
9. 条件操作符
exp1 ? exp2 : exp3
#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y) // get_max前的int为函数的返回类型;
{
return (x>y)?(x):(y); //x是否大于y如果是返回x如果不是返回y;表达式1为真就返回表达式2,
} //否则返回表达式3;
//调用结束后,形参单元被释放也就是数据无了,实参单元仍保留并维持原值。
int main() //实参与形参的类型应相同或赋值相兼容,num1与num2为int类型
//所以接收它们的x与y也是int类型。x与y是形参。
{
int num1 = 5;
int num2 = 10;
int max = get_max(num1, num2); //num1与num2是函数实参,用逗号隔开;
printf("max = %d\n", max);
return 0 ;
}
10. 逗号表达式
exp1, exp2, exp3, …expN
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//表达式1为0,a=2+10;表达式3为12,
printf("c=%d ",c); //b=12+1;取最后一个表达式的结果为整个表达式的结果。
return 0;
}
11. 下标引用、函数调用和结构成员
1. [ ] 下标引用操作符
int arr[5];//创建数组
arr[4] = 10;//实用下标引用操作符。
// [ ]的两个操作数是arr和5。
2. ( ) 函数调用操作符
#include <stdio.h>
void test1()
{
printf("你好\n");
}
int main()
{
test1(); // 实用()作为函数调用操作符。
return 0;
}
3. 访问一个结构的成员
#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;
}