又来到了崭新的一天,欢迎各位读者来到我的课堂详解c语言操作符,书接上回,我们学习了c语言操作符的算数操作符和移位操作符今天小编就把剩下的操作符讲解给大家。
操作符 | Value |
---|---|
算数操作符 | +, -, * , / ,% |
移位操作符 | 左移操作符(<<)右移操作符 (>>) |
位操作符 | 按位与(&)按位或( |
赋值操作符 | = += -= |
单目操作符 | |
关系操作符 | |
逻辑操作符 | && |
条件操作符 | 表达式1 ? 表达式2:表达式3 |
逗号表达式 | |
下标引用,函数调用和结构成员 |
提示:以下是本篇文章正文内容,下面案例可供参考
位操作符的操作数必须是整数
1,这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
2,按位与的运算就是两个都为1则为1,否则为0。
int main()
{
int a = 3;
int b = -3;
int c = a & b;
printf("%d",c);
}
分析 |
在这里整数在内存中存储的是补码,正整数的原码,反码,补码都相同,所以3在内存中存储的是它的原码,负整数在内存中存储的也是补码,得到如上图中一样,3的补码和-3的补码按位与,两个数两个都为1则为1,否则则为0,%d意味着打印一个有符号的整数,所以最终结果等于1.
这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
按位或的运算就是只要两个之中有一个为1则为1,两个0才为0
int main()
{
int a = 3;
int b = -3;
int c = a | b;
printf("%d",c);
}
分析 |
在这里讲3与-3的补码写出来 按位或的运算就是只要两个之中有一个为1则为1,两个0才为0;所以求得反码的值,最高位为符号位,所以求到他的值为负数的反码,在这里%d来打印就得求得他的原码二进制,转换成十进制,所以最终得到值为-1。
这里位代表二进制位,在上篇内容讲解了有关于二进制的知识,在这里小编就不再重复了。
按位异或相同为0;不相同(相异)为1
//按位异或
int main()
{
int a = 3;
int b = -3;
int c = a ^ b;
printf("%d", c);
}
分析 |
在这里先求出3和-3的补码,然后按位异或的运算就是相同为0,相异为1,所以求得3和-3的按位异或的值,但是他的最高位为1,是负数,要用%d打印出来所以我们得求出他的原码所以得到最终的值为-2.
在这里给大家讲解一个关于按位异或的小知识看到如下图:按位异或满足交换律
来做个习题:让13的第五位变成1,在让13的第五位变回来
int main()
{
int a = 13;
a |= (1 << 4); //1向右移动四位在和a或上得到13的二进制位第五位变成1
printf("%d \n", a);
a ^= (1 << 4); //异或得到原来的值 a &= (~(1<<4));
printf("%d ",a);
return 0;
}
一个等号叫赋值,两个等号叫相等,注意区分 !!!
int main()
{
int x = 0; //这个叫初始化
x = 100; //这个叫赋值
}
int main()
{
//int x = 0; //这个叫初始化
//x = 100; //这个叫赋值
int x = 10;
int a = 20;
int y = 0;
a = x = y + 1;//连续赋值
printf("%d %d %d",a,x,y);
}
分析 |
在这里y等于0;然后把y+1的值赋值给x,x=1,最后将x赋值给a,得到a等于1。也就是等于x=y+1;a=x;
操作数只有一个的叫单目操作符
例如:像a+b;+号两端有两个操作数a和b这个叫双目操作符
而!a,逻辑反操作符旁边就a一个操作数叫做单目操作符。
单目操作符 | 名称 |
---|---|
! | 逻辑反操作 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对一个数的二进制位进行按位取反 |
– | 前置和后置– |
++ | 前置和后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
在c语言中0表示假,非零表示真
逻辑反操作就是把假的变成真的,把真的变成假的。
int main()
{
int flag = 3;
if (flag)
printf("hehe\n");
return 0;
}
int main()
{
int flag = 3;
if (!flag)
printf("hehe\n");
return 0;
}
分析 |
在第一个代码中flag的值为3,3为非零代表真进入if里面判断,判断为真则执行if里面的语句printf (“hehe”);在第二个代码中,flag表示真,则!flag表示为假,if后面跟着判断,判断为假则不执行if语句中的内容,所以不打印hehe。
作用:取出一个变量在内存中的地址
int main()
{
int a = 10;
printf("%p",&a);
return 0;
}
分析 |
在这里对a进行取地址,取出a的地址我们用%p进行打印,%p是专门用来打印地址的。当然我们把程序关掉重新运行,我们发现这时地址是变化的,这时正常现象,程序重新运行,原先的存放的a就消除了,所以每次运行a都会重新开辟一个空间再去存放a,所以地址不一样。在这里注意,a在内存中占四个字节,每个字节都有地址,&a取的是a的第一个字节的地址也就是起始地址。
sizeof的操作数就是sizeof后面括号的内容,计算的是类型所创建的变量或者变量所占内存空间的大小
如要详细深刻理解请看小编写的: 详解sizeof和strlen
int main()
{
int a = 10;
int n = sizeof(a); //计算的是a所占内存的大小,单位是字节
printf("n=%d\n",n);
return 0;
}
验证sizeof不是函数的原因
如果sizeof是函数那么后面的括号不能省略,因为函数在调用的时候,后面的括号是不能省略的,所以sizeof是操作符,
作用:对一个数的二进制位进行按位取反
int main()
{
int x = 0;
printf("%d",~x);
return 0;
}
分析 |
在这里0在内存中存储的是0的补码,然后~0表示所有的二进制位按位取反得到反码,因为最高位为1,所以它是负数,负数要以%d的形式打印需求出它的原码所以得到-1。
++操作符分为两种,前置++和后置++
接下来代码演示
1,前置++作用:先加1后赋值
//前置++
int main()
{
int a = 10;
int b = ++a;
printf("%d\n",a);
printf("%d\n",b);
}
分析 |
2,后置++作用:先赋值后加1
//后置++
int main()
{
int a = 10;
int b = a++;
printf("%d\n", a);
printf("%d\n", b);
}
分析 |
而后置++,则是先将a的值赋值给b,然后再a+1,等同于b=a;a=a+1;最终得到a的值为11,b的值为10.
思考一下:a=10;printf(“%d\n”,a++);这个运算表达式结果是什么?
回答:先使用后++,先打印a的值,a再去加1
–操作符等同于++操作符一样的作用,在这里不再演示
1,前置- -:先减一,后赋值。
2,后置- -:先赋值,后减一。
这个操作符搭配地址使用
//*解引用操作符
int main()
{
int a = 10;
int* p = &a; //取出a的地址,放在p中,于是p就成了指针变量,而不是整型变量,指针变量类型就是 int *
printf("%p\n",p); //打印地址用%p
*p = 20;
printf("%d\n",a);
return 0;
}
分析 |
第一个*代表的是int 这个是指针变量的类型不是操作符;而p的意思是对p解引用,通过p里面存的地址找到它所指向的对象,也就是a,也就是说解引用p等价于a。我这里后面赋值20,也就是把20给到了a。
类型不同强制转换成需要的类型
在这里3.14是double类型转换成int类型下面就会报警告,可能会丢失数据。而我们需要一个整形的变量我么只需要强制类型转换成int类型的。
在这里小编主要讲一下等于操作符(==),注意的是并不是所有的对象都可以用等于号来比较的
例如:字符串的比较
区分逻辑与和按位与
逻辑与不关注二进制位,它只关注真假,两个真才为真,只要一个为假整体结果就是假,按位与是二进制位进行与
int main()
{
int x = 1 & 2;
int y = 1 && 2;
printf("%d\n", x);
printf("%d\n", y);
return 0;
}
分析 |
在这里按位与就不跟各位读者详细说了前面已经讲述,我们这里讲解一下逻辑与。在这里y=1&&2为啥等于1呢,这是因为逻辑与只关注真假,在计算机中0代表假,非零表示真,在这里1是真,2也是真,真逻辑与真,整体就是真所以y就是1.
在这里拓展一下,&&只要左边为假,右边就不在计算了,也就是短路现象。
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d\nb=%d\nc=%d\nd=%d\ni=%d\n", a, b, c, d, i);
return 0;
}
分析 |
区分逻辑或和按位或.
逻辑与也是只关注二进制位,但是他是只要有一个为真,整体结果就为真。
按位或关注的是二进制位,它是只要两个中有一个为1就为1 ,两个全部为0才为0.
int main()
{
int x = 1 && 0;
int z = 1 || 0;
int y = 1 | 0;
printf("%d\n", x);
printf("%d\n", z);
printf("%d\n", y);
return 0;
}
分析 |
在这里逻辑x= 1&&0;因为1是真0是假,逻辑与运算只要一个为假整体就为假。而z=1| | 0;在这里1为真0为假,逻辑或运算只要一个为真整体就为真,所以z的结果为1。
一般形式:表达式1?表达式2:表达式3;这个计算方法就是如果表达式1为真则表达式2计算,表达式3不计算,表达式2计算的结果就是整个表达式的结果;相反表达式1为假则表达式2不计算,表达式3计算,表达式3为整个表达式的结果。
int main()
{
int x = 3;
int y = x > 4 ? x + 1 : x - 1;
printf("%d",y);
return 0;
}
分析 |
逗号表达式就是用逗号隔开的多个表达式
语法形式为:表达式1,表达式2,表达式3,…表达式n
逗号表达式,从左向右依次进行。整个表达式的结果是最后一个表达式的结果
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
分析 |
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a + 10, a, b = a + 1);
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
分析 |
在这里讲述一下小编最开始学这个表达式容易搞混的东西,在这里可以清晰看到小编把第二个表达式改为a+10,而不是a=b+10;所以这里只是算出了a+10的结果但是并没有赋值给a,所以a的值还是1,最后算出的b也就是1+1得到2然后赋值给c。
在这里小编就不在多唠嗑下标引用操作符了,大家都在数组中学过了我就简单给各位读者概括一下
int main()
{
int arr[10]; //创建数组
arr[9] = 10; //使用下标引用操作符,令数组下标为9的数为10,在这里[]操作数为arr和9
return 0;
}
//函数定义
int add(int x, int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
//函数调用
int c = add(a, b);
return 0;
}
分析 |
在这里函数调用那里add后面的圆括号就是函数调用操作符,函数调用不能省略括号,他是一个函数调用操作符,在这里之前也讲述了sizeof为什么不是函数的原因,如果sizeof是函数那么函数调用的时候那个括号不能省略, 在这里函数调用操作符的操作数是add,a,b
在这里结构体操作符有两个
. 结构体.成员
->结构体指针->成员名
#include<string.h>
struct Stu
{
char name[20];
int age;
double score;
};
void set_stu(struct Stu* ps)
{
//strcpy((*ps).name, "zhangsan");
//(*ps).age = 20;
//(*ps).score = 100.0;
strcpy(ps->name, "zhangsan"); //通过ps结构体指针找到他所指向的对象成员
ps->age = 20;
ps->score = 100.0;
}
void print_stu(struct Stu ss)
{
printf("%s %d %lf",ss.name,ss.age,ss.score);
}
int main()
{
struct Stu s = { 0 };
set_stu(&s);
print_stu(s);
return 0;
}
一份耕耘一分收获,在此次学习中你已经学会了c语言操作符,如果大家还有什么不懂的可以在下方留言小编看到后会详细给大家解读一番,感谢观看!!完结撒花。