C语言中的操作符主要可以分为10个类型,这篇文章将带你详细了解各操作符的使用方法,希望能对你有帮助~
目录
1、算数操作符(+ - * / %)
/ 是除法运算符,与日常生活中的使用略有不同,分为两种情况
1、'/'左右两边都是整型:
2、'/'两边有一边是浮点型:
%是取模操作符
2、移位操作符( >> << )
原码、补码、反码:
<< 左移操作符
>> 右移操作符
3、位操作符( & ^ | )
4、赋值操作符( = += -= *= /= &= ^= |= >>= <<=)
5、单目操作符( ! - + & sizeof ~ -- ++ * (类型) )
1、逻辑反操作符 !
2、正值和负值操作符 + -
3、取地址操作符与间接访问操作符(解引用操作符) & *
4、sizeof操作符
5、~操作符
6、前置、后置-- 前置、后置++
7、(类型) 强制类型转换
6、关系操作符( > >= < <= != ==)
7、逻辑操作符( && || )
8、条件操作符 ( exp1 ? exp2 : exp3 )
9、逗号表达式( exp1, exp2, exp3, …expN )
10、下标引用、函数调用和结构成员( [] () . -> )
1、下标引用操作符 [ ]
2、函数调用操作符 ()
3、访问一个结构的成员
在算数运算符中,+ - * 对应的就是我们数学中的加减乘三项,用法也是相同的。
#include
int main()
{
int a = 1, b = 2, sum = 0;
//a与b相加
sum = a + b;
//a与b相减
sum = a - b;
//a与b相乘
sum = a * b;
return 0;
}
若'/'左边的数大于右边,则得出的结果是取商的那部分;若'/'左边的数小于右边,则得到的结果为0
#include
int main()
{
int a=5, b=2;
int sum = a / b;
printf("%d ", sum);//此时打印出来的结果为2
//5除以2 商2余1
a = 2, b = 5;//将a b重新赋值
sum = a / b;
printf("%d ", sum);
//此时打印出来的结果是0
return 0;
}
如果 '/' 两边都是整型,就算是将返回值类型定义为浮点型,计算出来的结果也只会是一个整数。
在除法运算中,只要有一个操作数是浮点数,就是浮点数的除法运算;所谓浮点数的除法运算就是,最后的结果是一个浮点数。
#include
int main()
{
double sum = 5 / 2.0;
printf("sum = %lf \n", sum);
//此时打印出来的结果为2.5
sum = 2 / 5.0;
printf("sum = %lf \n", sum);
//此时打印出来的结果是0.4
return 0;
}
取模操作符,取的是一个数除另外一个直至除不尽的余数,若取模对象刚好是自己的公约数,则结果为0。
例如 5%1=0 5%2=3 5%3=2 5%4=1 5%5=0
注意:取模的对象不能为0,且不能为浮点型,必须为整数!
#include
int main()
{
int a, b, sum;
scanf("%d %d", &a, &b);
sum = a % b;
printf("%d", sum);
//若a=5 b=2 则sum=1
return 0;
}
在介绍移位操作符前,我们需要先了解原码,反码,补码是什么,以及他们之间的联系与转换。
原码、补码、反码:
整数在内存中存储的是补码的二进制序列,整数在计算的时候使用的也是补码
所以在接下来移位操作符的使用中,我们也要注意原码、反码、补码间的转化 。
左移操作符可以将一个二进制数向左移动指定的位数,移动后在右侧补0。操作后不会让数据变化,需要用赋值操作符才能保存下来。
//移位规则:左边抛弃,右边补0
#include
int main()
{
int a = 7;
//7的二进制序列补码为 00000000000000000000000000000111
//经过左移操作符移动一位得 00000000000000000000000000001110
//将二进制转化为十进制可得结果为 14
//①
a << 1;
printf("①:%d\n", a);
//②
int b = a << 1;
printf("②:%d\n", b);
//③
printf("③:%d\n", a<<1);
return 0;
}
运行结果如图所示,证明操作后不会让数据变化,需要用赋值操作符才能保存下来。
右移运算分为两种:
1、逻辑右移
左边用0填充,右边丢弃
2、算数右移
左边用原该值的符号位填充,右边丢弃
在不同的编译器中,右移操作符的实现不同,绝大多数编译器中是以算数右移的方式来实现的。
//移位规则:右边抛弃,左边补符号位
#include
int main()
{
int a = -7;
//-7的二进制序列原码为 10000000000000000000000000000111
//-7的二进制序列反码为 11111111111111111111111111111000
//-7的二进制序列补码为 11111111111111111111111111111001
//经过右移操作符移动一位得 11111111111111111111111111111100
//转化为原码可得 10000000000000000000000000000100
//将二进制转化为十进制可得结果为 -4
//①
a >> 1;
printf("①:%d\n", a);
//②
int b = a >> 1;
printf("②:%d\n", b);
//③
printf("③:%d\n", a >> 1);
return 0;
}
运行结果如图所示,证明操作后不会让数据变化,需要用赋值操作符才能保存下来。
& 按位与 只要有0则为0,两个为1才为1
| 按位或 有1则为1
^ 按位异或 相同为0,相异为1
注意:他们的操作数必须是整数
& 按位与:
| 按位或:
^ 按位异或 :
代码练习:
#include
int main()
{
int a = 5;
int b = 1;
printf("a & b = %d \n", a & b); //打印 1
printf("a | b = %d \n", a | b); //打印 5
printf("a ^ b = %d \n", a ^ b); //打印 4
return 0;
}
赋值操作符 ,就是将一个数赋值赋给变量,从右向左赋值。这方面的内容比较简单,我们用一串代码来辅助理解
#include
int main()
{
int a = 0; //将0赋给a
int b;
int c;
b = c = 0; //赋值操作符还可以连续操作,将0赋给b c
//+= 若我们想表示a=a+1 或a=a+b 等,那我们就可以这样表示
a += 1;
a += b;
//-= 若我们想表示a=a-1 或a=a-b 等,那我们就可以这样表示
a -= 1;
a -= b;
//*= 若我们想表示a=a*1 或a=a*b 等,那我们就可以这样表示
a *= 1;
a *= b;
//下面的各个操作符都是一样的用法,大家可以自己去试试看
return 0;
}
! 逻辑反操作- 负值+ 正值& 取地址sizeof 操作数的类型长度(以字节为单位)~ 对一个数的二进制按位取反-- 前置、后置--++ 前置、后置++* 间接访问操作符(解引用操作符)(类型) 强制类型转换
逻辑反操作可用于 把真变假,把假变真
例如:
#include
int main()
{
int a = 1;
int b = 0;
if (a)
printf("111\n");
if (!a) //把真变假
printf("222\n");
if (b)
printf("333\n");
if (!b) //把假变真
printf("444\n");
return 0;
}
一个数加上正号还是它本身,加上负值变成相反数
例如:
&与 * 经常搭配使用,&用于取出想要变量的地址
例如:
#include
int main()
{
int a = 10;
int* p = &a; //a变量的地址
//*p是对p进行解引用操作,*p是通过p中存放的地址,找到p指向的对象
//*p其实是a
*p += 1;
printf("a = %d\n", a);
return 0;
}
我们这边定义了一个整型a,给他赋值10;又定义了一个变量p来存放a的地址。
p是用来存放地址的,那么p就应该是一个指针变量。' * ' 即代表p是一个指针,前面的int说明变量p指向的类型是整型,“int *”合起来就是p的类型。
*p是对p进行解引用操作,*p是通过p中存放的地址,找到p指向的对象,*p其实是a。那么我们修改*p的值即也能改变a的值。所以a的值为:
sizeof求的是变量(类型)所占空间的大小,单位是字节。
可以用来求变量大小也可以用来求类型大小:
#include
int main()
{
int a = 10;
char b;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(b));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(char));
}
且sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
#include
int main()
{
int a = 10;
char b[10];
int c[10];
printf("%d\n", sizeof(b));
printf("%d\n", sizeof(c));
}
注意:
我们要注意区分sizeof和strlen,sizeof是一个操作符,strlen是库函数。
#include
int main() { int a = 10; printf("%d\n", sizeof(a)); printf("%d\n", sizeof a); } 这两种写法都可以,证明sizeof是操作符而不是函数,函数不能省略(),而sizeof可以省略
~可以对一个数的二进制按位取反
#include
int main()
{
int a = 1;
//000000000000000000000001
// 取反后
//111111111111111111111110 补码
//111111111111111111111101 反码
//100000000000000000000010 原码
printf("%d", ~a);
return 0;
}
取反是针对一个数的补码来取反,因为整数在内存中存储的是补码的二进制序列,整数在计算的时候使用的也是补码。当我们打印时要把它变回原码,来打印。
前置++或 -- 都是先 +1或-1 再使用;后置 ++或 -- 都是使用,再+1或 -1。
#include
int main()
{
int a = 5;
int b = 0;
b = ++a; //前置++,先+1再使用,所以b=a=6
printf("a = %d b = %d\n", a, b);
b = a++; //后置++,先使用再+1,所以a=7,b=6
printf("a = %d b = %d\n", a, b);
// --与++用法相同
return 0;
}
强制类型转换,我们可以将一个数据直接转换为我们需要的类型。例如:
#include
#include
#include
int main()
{
int a = (int)3.14;
//3.14会默认被编译器认为是double型
//我们将他强制传换为int型
//还有我们常用的用来生成随机数的srand函数
//time函数的返回类型是time_t,但srand的参数类型需要时无符号整型
//所以在这里将他强制类型转换,然后就可以顺利使用了
srand((unsigned int)time(NULL));
rand();
return 0;
}
>>=<<=!= 用于测试“不相等”== 用于测试“相等”
这些关系运算符比较简单,我们要注意一些运算符使用时候的陷阱。
注意:在编译过程中,= 和 == 不小心写错,会导致错误。
'='是赋值操作符,'=='是测试两个数相等的操作符
&& 逻辑与|| 逻辑或
借助两道编程题来辅助我们理解:
①
②
逻辑或有一个判断的条件为真就为真,当已经判断了一个条件为真,剩下的条件就不需要再继续判断了,整个式子的判断为真。
条件操作符,当表达式一判断为真,则输出表达式二的结果;当表达式一判断为假,则输出表达式三的结果。
#include
int main()
{
int a = 1;
int b = 2;
//可以用来判断两个数中的较大值
printf("%d", a > b ? a : b);
return 0;
}
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
#include
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a += b, b += 1);
//此时a等于多少?
//b等于多少?
//c等于多少?
//a>b判断为假会影响后面的计算吗?
printf("%d \n", c);
return 0;
}
编译后的结果为:
所以我们可以知道,逗号表达式中判断为真或为假,不影响表达式的进行;表达式中进行的运算会对值产生影响;且整个表达式的值为最后一个表达式的值。
操作数:一个数组名+一个索引值(所有值就是下标值)
#include
int main()
{
int arr[10];//创建数组
arr[9] = 10;//使用下标引用操作符
return 0;
}
[ ]的两个操作数分别是 arr 和 9 。一个是数组名,一个是下标值。
函数调用操作符接受一个或多个操作数:第一个操作数是函数名,剩余的操作数是传递给函数的参数。
#include
void test1()
{
printf("调用了test1\n");
}
void test2(int x)
{
printf("调用test2打印了 %d\n", x);
}
int main()
{
test1();//第一个操作数是函数名 test1
test2(100);//第一个操作数是函数名 test1,第二个操作数是传递的参数
return 0;
}
· 结构体.成员名
-> 结构体指针->成员名
这方面的知识也比较简单,我们利用一段代码来辅助我们理解。
#include
struct Stu
{
int age;
char name[10];
};
void Print(struct Stu* s) //结构体指针
{
printf("%d %s\n", s->age, s->name); //结构体指针 -> 成员名
printf("%d %s\n", (*s).age, (*s).name);
}
int main()
{
struct Stu stu = { 18,"张三" };
printf("%d %s\n", stu.age, stu.name);// 结构体 . 成员名
Print(&stu);
return 0;
}
以上就是 C语言基础:操作符详解,看这一个就够了!(内含详细图解)的全部内容,如果对你有帮助的话希望得到你的三连支持!