目录
前言
1.sizeof
2.自增和自减(++、- -)
编辑3.逻辑操作符
4.条件操作符(exp1?exp2:exp3)
5.逗号表达式(exp1,exp2,exp3,……)
6.地址操作符(*、&)
7.下标引用、函数调用和结构成员([]、()、.、->)
7.1[]下标引用操作符
7.2()函数调用操作符
7.3访问一个结构成员
8.关系操作符
9.操作符的属性
总结
操作数详解(上)的链接:
http://t.csdnimg.cn/Nwd9i
sizeof是求操作数的类型长度(以字节位单位)
sizeof(类型名),类型名也可以是变量的名字。
有好多人认为sizeof是函数,但是函数在调用时必须带有()才能被使用,但sizeof在使用时可以不带(),所以sizeof其实是一个操作符。
注意:只有在用变量名时才能省略(),其他情况不能省略。
sizeof在涉及到数组时要注意 。
#include
void test1(int arr[])
{
printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//(4)
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr));//(1)
printf("%d\n", sizeof(ch));//(3)
test1(arr);
test2(ch);
return 0;
}
问 (1)、(2)输出什么,(3)、(4 )输出什么
答案:(1)、(2)输出40、4或8,(3)、(4 )输出10,4或8
为啥是4或8呢,是因为arr传过去的是数组首元素的地址,函数用指针接收的,所以sizeof求的是指针的类型长度,在32位情况下是4个字节,在64位情况下是8个字节。
自增和自减有前置(++i,- -i)和后置(i++,i- -)之分,前置是先++(- -)再使用操作数,后置是先使用操作数再++(- -)。
&& 逻辑与
|| 逻辑或
! 逻辑非
逻辑与运算规则:全真为真,有假为假。
逻辑或运算规则:全假为假,有真为真。
逻辑非运算规则:是真为假,是假为真。
C语言中零表示假,非零表示真。
区分逻辑与和按位与 区分逻辑或和按位或
按位与和按位或作用的是二进制位,而逻辑与和逻辑或作用的是表达式的真假。
例子:
1&2----->0
1&&2---->1
1|2----->3
1||2---->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\n", a, b, c, d);
return 0;
}
//程序输出的结果是什么?
答案:
我们可以看到只有a自增1了,其他的自增都没有执行,这就体现了逻辑与的短路,因为a是后置++,先使用a=0,逻辑与有假为假,所以右侧的++b不用计算也知道a++&&++b的值为0 ,所以++b就被短路了,没有执行,后边的d++也是一样。
通过我的讲解,大家也可以练习一下,看看下面的代码结果是什么,可以把答案打在评论区。
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\n", a, b, c, d);
return 0;
}
运算规则:表达式1的值为真,结果就为表达式2的值,为假,结果就为表达式3的值。
if ( a > 5 )b = 3 ;elseb = - 3 ;转换成条件表达式,是什么样?
答案:a>5?b=3:b=-3;
我们可以看到一些简单的if else语句可以用条件操作符替代来简化代码。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);
//c的值为多少
有的人认为c的值为2,但其实是13,虽然逗号表达式的结果为最后一个表达式的结果,但是前面表达式的结果对后面表达式的值也有影响。
逗号表达式也有简化代码的作用
a = get_val();
count_val(a);
while (a > 0)
{
//业务处理
a = get_val();
count_val(a);
}
如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{
//业务处理
}
如果你想得到一个变量的地址,你可以使用&(取地址操作符)。
如果你想得到一个地址指向位置的内容可以使用*(解引用操作符)
例子:
1.得到变量地址
int a= 0;
int* p = &a;
//这样指针p就得到了变量a的地址。
2.得到地址内容
int a= 0;
int* p = &a;
int b = *p;//与b = a效果一样
int arr [ 10 ]; // 创建数组arr [ 9 ] = 10 ; // 实用下标引用操作符。[ ] 的两个操作数是 arr 和 9 。
#include
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1(); //实用()作为函数调用操作符。
test2("hello bit.");//实用()作为函数调用操作符。
return 0;
}
. 结构体.成员名
-> 结构体指针 -> 成员名
当我们创建了一个结构体变量时,我们想访问里面的成员变量就可以使用 . 来访问,当我们通过函数把地址传给结构体指针时,可以通过->来访问成员变量。
例子:
#include
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;
}
>>=<<=!= 用于测试 “ 不相等 ”== 用于测试 “ 相等 ”
警告: 在编程的过程中== 和=不小心写错,导致的错误。
复杂表达式的求值有三个影响的因素。1. 操作符的优先级2. 操作符的结合性3. 是否控制求值顺序。两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
但是就算我们知道了操作符的优先级,我们还是不能准确的判断表达式的结果。
例子如下:
一些问题表达式
代码1:a * b + c * d + e * f
所以表达式的计算机顺序就可能是:
a*bc*da*b + c*de*fa*b + c*d + e*f或者:a*bc*de* fa*b + c*da*b + c*d + e*f
代码2:c + --c;
通过上边的几个例子,我们也感受到了,就算知道了优先级吗,有些表达式也是不能确定的的,所以我们以后写代码,尽量少写问题代码,把表达式写的简洁好理解,可以使用括号来确定运算顺序。
操作符优先级表
到这里操作符的讲解就都结束了,希望各位读者能有所收获,感谢大家的阅读,欢迎各位大佬在评论区留言哦~!!!