目录
1. 结构成员访问操作符
1.1 结构体
1.2结构体成员访问操作符
1.2.1 直接访问
1.2.2 间接访问
2. 操作符的属性
2.1 优先级
2.2 结合性
3. 表达式求值
3.1 整型提升(类型小于int)
3.2 算术转换(类型大于int)
1. 结构成员访问操作符
1.1 结构体
C语言中提供了许多内置类型,如:char、short、int、long、float、double等,但是只要这些是远远不够的,C语⾔为了解决,增加了结构体这种⾃定义的数据类型,让程序员可以⾃⼰创造适合的类型。
结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:
标量、数组、指针,甚⾄是其他结构体。(结构体成员至少一位)
struct tag
{
member-list;
}variable-list;
假如描述一个学生:
struct Stu
{
char name[20];//名字
int age;//年龄
float score;//成绩
}s3,s4;//这里的分号不能忘了 s3,s4也是结构体变量,但是是全局变量
int main()
{
struct Stu s1;//创建的结构体变量,局部变量
struct Stu s2;
return 0;
}
//结构体初始化
struct Stu
{
char name[20];//名字
int age;//年龄
float score;//成绩
}s3={"wangwe",33.66.0f},s4={"翠花",18,100.0f};//初始化
int main()
{
struct Stu s1={"zhangsan",20,95.5f};//初始化
struct Stu s2={"lisi",18,87.5f};
return 0;
}
//结构体包含结构体
struct Point
{
int x;
int y;
};
struct Data
{
int num;
struct Point p;
};
int main()
{
struct Data b = { 100,{1,2} };
return 0;
}
1.2结构体成员访问操作符
1.2.1 直接访问
使⽤⽅式:结构体变量.成员名
结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如下所示:
#include <stdio.h>
struct Point
{
int x;
int y;
}p = {1,2};
int main()
{
printf("x: %d y: %d\n", p.x, p.y);//直接访问
return 0;
}
1.2.2 间接访问
有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。这时就要用到间接访问
使⽤⽅式:结构体指针->成员名
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main()
{
struct Point p = { 3, 4 };//结构体变量
struct Point* ps= &p;//结构体指针,指针指向p的地址
ps->x = 10;
ps->y = 20;
printf("x = %d y = %d\n", ps->x, ps->y);
return 0;
}
2. 操作符的属性
C语⾔的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。
2.1 优先级
优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。相邻操作符,优先级高的先执行,优先级低的后执行!!!
1+2*3
//这里我们知道肯定先算乘,后算加
2.2 结合性
如果两个运算符优先级相同,这时候就看结合性了,根据运算符 是左结合,还是右结合,决定执行顺序。
1*2/3
//这里乘和除的优先级相同,他们都是左结合运算符,所以从左到右执⾏
3. 表达式求值
3.1 整型提升(类型小于int)
C语⾔中整型算术运算总是⾄少以默认整型类型的精度来进⾏的。为了获得这个精度,表达式中的字符(char)和短整型(short)操作数在使⽤之前被转换为普通整型(int),这种转换称为整型提升。
int main()
{
char c1 = 125;
char c2 = 12;
char c3 = c1+c2;
printf("%d\n", c3);
return 0;
}
如何进⾏整体提升呢?
//负数的整形提升
char c1 = -1;
变量c1的⼆进制位(补码)中只有8个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的⼆进制位(补码)中只有8个⽐特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//⽆符号整形提升,⾼位补0
//举例
int main()
{
//char 类型的取值范围是-128——127
char c1 = 125;
//01111101-c1-有符合的char
char c2 = 10;
//00001010-c2-有符合的char
char c3 = c1+c2;
//10000111-c3
//11111111111111111111111110000111-c3--提升后(补码)
printf("%d\n", c3);
return 0;
}
3.2 算术转换(类型大于int)
如果某个操作符的各个操作数属于不同的类型,那么除⾮其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就⽆法进⾏。下⾯的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
//如果某个操作数的类型在上⾯这个列表中排名靠后,
//那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
注意:即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯⼀的计算路径,那这个表达式就是存在潜在⻛险的,建议不要写出特别负责的表达式。