*
&——取地址操作符 两个操作数就是按位与,一个操作数就是取地址操作符
int main()
{
int a = 10;
printf("%p\n",&a);
int *pa = &a;//pa是用来存放地址的,pa就是一个指针变量
*pa = 20;//*解引用操作符
printf("%p\n",a); //20
return 0;
}
(类型)——强制类型转换
int main()
{
int a = (int)3.14;
return 0;
}
6、关系操作符
注:比较两个字符串相等不能使用==
7、逻辑操作符
&& 逻辑与——一个为假则为假,两个为真才为真
|| 逻辑或——一个为真则为真,两个为假才为假
int main()
{
int a = 30;
int b = 0;
if(a&&b) //a为真且b为真才能进去
{
printf("hehe\n");
}
return 0;
}
int main()
{
int a = 30;
int b = 0;
if(a||b) //一个为真就为真
{
printf("hehe\n");
}
return 0;
}
题目中,a为后置++,先使用再++,开始a=0,所以&&++b没计算,而且d++也没计算,因此最终b、c、d都没变,而a已经使用了,所以++后变成1
若把a改成1,结果是?
输出将结果:2335
a为1,因为1为真,所以a++ && ++b会进行运算,b本来是2,经过前置++后变成3,运算后a后置++变成了2,因为a++ && ++b为真,所以&& d++会运算,最后d后置++变成5.
这个代码的输出结果是?
int main()
{
int i = 0; int a = 1;int b = 2;int c = 3;int d = 4;
i = a++ || ++b || d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}
int c = a || b如果左边为真,则后边不计算
a为1,1为真,则|| ++b不计算,使用后a自增变成2,因为前面结果为真,|| d++也不计算
这个代码的输出结果是?
int main()
{
int i = 0; int a = 0;int b = 2;int c = 3;int d = 4;
i = a++ || ++b || d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}
输出结果
区分:
8、条件操作符(三目操作符)
int main()
{
int a = 3;
int b = 0;
if(a>5)
b = 1;
else
b = -1;
//三目操作符
b = (a > 5 ? 1 : -1);
//a>5吗,如果大于则b=1,否则b=-1
//a>5——表达式1,1——表达式2,-1——表达式3
return 0;
}
a b比大小
max=(a>b ? a : b);
9、逗号表达式
// 逗号表达式会从左向右依次计算,但最后起作用的只有d>0表示式。
//逗号表达式避免了代码冗余。
10、下标引用、函数调用和结构成员
(1)[ ]下标引用操作符
操作数:一个数组名+一个索引数
(2)()函数调用操作符 接受一个或者多个操作数:第一个操作数是函数名,剩下的操作数就是传递给函数的参数。
(3)结构成员访问操作符
结构成员访问操作符
.使用方式:结构体.成员名
->使用方式:结构体指针->成员名
结构体
int float char short......
//.使用方式:结构体.成员名
书:书名、书号、定价
struct//定义新的结构体类型
struct Book
{
char name[20];
char id[20];
int price;
//name、id、price是结构体成员(变量)
};
int main()
{
struct Book b = { "c语言","c20210509",55 };
printf("书名:%s\n", b.name);
printf("书号:%s\n", b.id);
printf("定价:%d\n", b.price);
return 0;
}
//法一
#include<stdio.h>
struct Book
{
char name[20];
char id[20];
int price;
};
int main()
{
struct Book b = { "c语言","c20210509",55 };
struct Book * pb = &b;
printf("书名:%s\n", (*pb).name);
printf("书号:%s\n", (*pb).id);
printf("定价:%d\n", (*pb).price);
return 0;
}
//通过*pb解引用找到b,b.name就找到了成员
//法二
//->使用方式:结构体指针->成员名
#include<stdio.h>
struct Book
{
char name[20];
char id[20];
int price;
};
int main()
{
struct Book b = { "c语言","c20210509",55 };
struct Book * pb = &b;
printf("书名:%s\n", pb->name);
printf("书号:%s\n", pb->id);
printf("定价:%d\n", pb->price);
return 0;
}
11、表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
int main()
{
int a = 3;
int b = 5;
int c = a + b * 7;
return 0;
}
//先算乘再算+就是优先级的体现
不过在计算表达式的时候可能会出现类型转换,通常遇到的就是隐式类型转换。
隐式类型转换
b+c的结果要放到a中,但是b和c是char类型,它们没有达到整型的大小,所有这是他们会先提升成普通整型在进行运算,运算完后,因为a是字符类型,b+c的结果放不下,所以这时要把b+c的结果截断,储存到a中。
发现a和b都是char类型,都没有达到一个int的大小,这里会发生整型提升
a-00000011
b-01111111
a+b会发生整型提升
//如何整型提升呢?——整型提升是按照变量的数据类型的符号位来提升的
00000011的最高位是0,整型提升补的是符号位,提升完的结果是00000000000000000000000000000011
//b提升后变成00000000000000000000000001111111
//00000000000000000000000000000011
//00000000000000000000000001111111
相加结果00000000000000000000000010000010
截断10000010——c
//但是,打印的是整型,所以还会发生整型提升
10000010的最高位是1,所以补1,提升后的结果是11111111111111111111111110000010,得到了补码,
//补码——11111111111111111111111110000010
//反码——11111111111111111111111110000001
//原码——00000000000000000000000001111110
最终结果是-126.
例子:
任何一个表达式都有两个属性:1、值属性 2、类型属性
整型提升针对的是自身大小无法达到int的大小
隐式类型转换的另一种就是算术转换
操作符属性
注:上表的优先级逐级递减
一些问题表达式