--C语言提供了内置类型:int、char等,但这还不够;假如来描述一更具体的东西,比如书、学生……就要从多方面描述,这时候单一的内置类型行不同。
--在C语言中提供了结构体这种自定义的数据类型,应对多种情况。
结构体是一些值的集合,这些值称为成员变量。结构体的每个成员都可以是不同类型的变量;比如:数组、指针、其他结构题、体等等
struct tag//struct表明是结构体
{
member-list;//一个或多个成员变量
}variable - list;//变量列表
//variable - list; 可有可无,在声明变量类型是可同时定义的变量,且为全局变量--描述学生
struct Stu
{
char name[20];//名字拼音
int age;//年龄
char id[20];//学号
float score;//成绩
//……
};//分号绝对不能丢--代码块1:结构体变量的定义
struct Stu
{
char name[20];//名字拼音
int age;//年龄
char id[20];//学号
float score;//成绩
//……
}s1,s2;//全局变量
struct Stu s3;//全部变量
int main()
{
struct Stu s4;//局部变量
return 0;
}--代码块2:初始化
//一般按顺序初始化
int main()
{
struct Stu s4 = {"zhnagsan", "202410102", 85.5f};//局部变量
struct Stu s5 = {"cuihua", "2024152331", 96.5f};
return 0;
}
//指定顺序初始化
struct Stu s6 = {.age = 20, .name = "wangcai", .score = 67.7f};--涉及到了 "."运算符。
--代码块:结构体嵌套初始化
//结构体-人声明
struct Peo
{
char name[30];
int age;
char tele[12];
};
//结构体-电话本声明
struct Ebook
{
struct Peo data[100];//可以存放100个人的消息
int count;//当前已存的个数
};
int main()
{
//结构体嵌套初始化
struct Peo p1 = { "zhangsan",20,"15598875462" };
struct Ebook eb = { {{"wangwu",19,"13564562077"},{"cuihua",18,"15827602564"}},0 };
return 0;
}--直接访问的操作是通过点操作符(.)实现的,接收两个操作数:
int main()
{
//结构体嵌套初始化
struct Peo p1 = { "zhangsan",20,"15598875462" };
struct Ebook eb = { {{"wangwu",19,"13564562077"},{"cuihua",18,"15827602564"}},0 };
//直接访问
//单个对象
printf("%s\n", p1.name);
printf("%d\n", p1.age);
printf("%s\n", p1.tele);
//多个对象
printf("%s\n", eb.data[1].name);
printf("%d\n", eb.data[1].age);
printf("%s\n", eb.data[1].tele);
return 0;
}-- . :结构体成员访问操作符 -- 使用方法: 结构体变量.结构体成员
--操作符有者两个重要的属性:优先级、结合性,这两个属性决定了表达式求值的顺序。
--优先级指:一个表达式包含多个运算符,哪个先执行,各种操作符i的优先级不同。
3 + 4 * 5;--在上面的例子,由于乘法运算符优先级高于加法运算符,则先计算4 * 5,再计算加法。
--两个运算符的优先级相同,则就需要结合性来判断;根据运算符是左结合、右结合来决定顺序。大部分为左结合(从左到右执行),少部分右结合(赋值运算符=)。
5 * 6 / 2;--上例中,因为*、/的优先级相同,看结合性都是左结合,那就从左向右执行,先*再/。
--优先级顺序很多,先记住下面常用运算符的优先级(从高到低),其余随用随查。
--注意:圆括号优先级最高,可以用它改变其他运算符优先级。

--C语言中整型算术运算总是至少以缺省 (默认) 整型类型的精度来进行的。为了获取这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
--整型提升意义: CPU 的整数运算器(ALU)通常以
int的长度(如 32 位或 64 位) 作为标准操作数大小。直接处理char(8 位)、short(16 位)等小类型效率低; C 语言要求:所有小于int的整型(如char、short)必须先提升为int或unsigned int,再参与运算。
--实例
char a, b, c;
...
a = b + c;--b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。
--如何进行整型提升?(看数值的类型)
//负数的整形提升
char c1 = -1;
//变量c1的⼆进制位(补码)中只有8个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的⼆进制位(补码)中只有8个⽐特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//⽆符号整形提升,⾼位补0--若某个操作符的操作数属于不同的类型,除非其中一个操作数转换为另一个操作数类型,不然操作无法执行。下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int--根据顺序可知,操作数的类型在上面这个列表中排名靠后,首先转换为另一个操作数的类型后再执行运算。
//表达式的求值部分由操作符的优先级决定。
//表达式1
a*b + c*d + e*f-- 注意:计算的时候,*比+的优先级高,只能保证*的计算是比+早。但优先级并不决定第三个*比第一个+早执行。(所以写代码时,最好用括号来区分先后)
//表达式2
c + --c;-- c=5
--如果左操作数的获取在右操作数之前则结果为 5+4=9; --如果左操作数的获取在右操作数之后则结果为 4+4=8;
//表达式3
int main()
{
int i = 10;
i = i-- - --i * (i = -3) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}--表达式3在不同编译器中测试结果:非法表达式程序的结果

#include <stdio.h>
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();
printf("%d\n", answer);//输出多少?
return 0;
}--上面的代码也存在着顺序问题:上述代码 answer=fun() - fun() * fun();中我们只能通过操作符的优先级得知:先算乘法,再算减法。
--函数的调用先后顺序无法通过操作符的优先级确定。
//表达式5
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
//尝试在linux 环境gcc编译器,VS2013环境下都执⾏,看结果。--当在不同的编译器上运行时,发现在gcc中是 10 4、在vs2中是 12 4。
--因为这个代码中的第一个+在执行的时候,第三个++是不是执行,这个不确定。因为依靠操作符的优先级和结合性是无法决定第一个+和第三个前置++的先后顺序。
结语:本篇文章承接上一篇博客,分享了关于操作符剩余知识,一定要好好理解;如果这篇文章对你的学习有帮助的话,欢迎一起讨论学习,你这么帅给个三连吧~~~