当前位置: 首页 > java >正文

硅基计划 学习总结 拾


一、结构成员

##引子##

如果我么想规划一个区域来存储我们的相关信息,但又不想很杂乱的存储,那我们可以用到结构体这个函数,来帮助我们结构化管理信息,我们暂时只介绍“.”

1.结构体

它可以用于复杂的、多个对象的,属于自定义数据类型,你可以自定义一些值的集合,值可以是不同类型的变量,甚至是嵌套结构体

我们给出示例:

struct tag(函数名)
{//一些成员列表
}(变量的列表,可有可无,可以在创建结构化函数时候创建变量,默认是全局变量);

##我们给出一段代码,参照上面的注释,我想你应该能明白,这里不过多赘述啦

struct adr
{char name[10];
};struct stu//先规定好结构体内部信息
{struct adr one [10];//这里的one是结构体名称char name[10];int age;float score;
};int main()
{//struct stu s1 = {"xiao_san",20,95.5f};//我们可以利用这个结构体存储不同的信息,这里s1代表一号学生//我们也可以不按照顺序初始化,可以指定初始化内容,利用“.”/*struct stu s1 = { .name = "zlh",.age=18,.score=95.5 };*///如果结构体里面套一个结构体呢?这个时候我们如何初始化呢?struct stu s3 = { {"heihei"},"wangwu",20,99.9f };//这里我们的括号里的括号就是针对adress来初始化的,如果里面还有数组,我们再加括号即可printf("%s\n", s3.one[0].name);//你可以添加多个“.”来访问多层结构体里的元素,注意结构体中你规定的存了10个信息,下标也是从0开始return 0;
}

二、操作符优先级

1.优先级

表达式含有各个运算符,优先级高的先执行,例如3+4*5=23;

2.结合性

假设优先级相同,那这个时候结合性说了算,究竟是左结合还是右结合,大部分都是左结合,少部分右结合,例如5*6/2=15,具体参照下表:

##你肯定想到这么多,我们懒得记,我们就记一些常用的吧

1.圆括号( () ),自增运算符( ++ ),自减运算符(-- )

2.单目运算符( + 和 ) • 乘法( * ),除法( / ) • 加法( + ),减法( )

3.关系运算符( < 、 > 等)

4.• 赋值运算符( = )

如果你不想这么麻烦,有一个终极办法,你想哪个部分先计算,就把哪个部分用括号括起


 


 

三、表达式求值

1.整型提升

整型默认是int类型,如果你想用long long类型你只需在数据后加上字母“ll”,为了获得这种精度,表达式中字符和短整型使用之前要被转化为普通整型

整型提升规则

1.有符号整型按照变量的数据类型的符号位提升,即其他位要么补0要么补1

2.无符号整数提升高位直接补0

为什么要这样做,这是因为CPU难以用除4字节或者8字节其他非4字节类型计算

##我们举个例子:

int main()
{char a = 20;char b = 120;char c = a + b;printf("%d", c);//为什么结果是-116?return 0;
}

为什么结果是-116?为什么你正数结果后面给我搞出个负数?诶,我们娓娓道来

##拓展:%d我们也可以十进制形式打印一个有符号整型int

1.首先我们要知道char类型的取值范围是-128~127,而你变量C求出来后是140,存不下呀

2.而且你char类型的变量只能接收一个字节大小,即8个比特位,对于二进制8位,那必然要对你二进制表示进行取舍

3.我们开始存取数据

变量a的值是20,转化成二进制后的补码是0000 0000 0000 0000 0000 0000 0001 0100,而你char类型只能存8比特位,即存入0001 0100,相当于把20这个值截断后存入

同理我们来存入b变量值120,转化成二进制补码是0000 0000 0000 0000 0000 0000 0111 1000,同理char类型变量我们存入8比特位,即0111 1000

4.要想相加,你只有8比特位显然是不行的,要进行整型提升,按照规则,a提升后为(高位补0):0000 0000 0000 0000 0000 0000 0001 0100,同理b为:0000 0000 0000 0000 0000 0000 0111 1000,我们再把两个整型提升后的变量相加,结果是:0000 0000 0000 0000 0000 0000 1000 1100

5.我们再把这个变量存入char类型中,截断后为1000 1100,但是你打印类型是整型,我们得再次发生整型提升(根据规则,符号位是1,我们高位补1)之后再转换成原码进行打印:1000 0000 0000 0000 0000 0000 0111 0100,打印的结果就是-116了

##怎么样,看似简单的算式背后可是有很复杂的逻辑

 2.算数转化:如果你的各个操作数属于不同类型,我们要将其中一个操作数类型转化成另外一个操作数类型,我们根据下面这个表由下到上转化优先级(int是起点)

感谢比特教育科技提供的图解,感谢

四、问题表达式

##有时候有些人在写程序,也不知道脑回路是怎样的,写的程序让编译器都不知所措

1.加法优先级问题

a*b+c*d+e*f;

 这个表达式如果是你,你肯定先算乘法再加起来

但是机器不管这些,都有自己独特算法

比如我们先计算前两个乘法,相加后,第三个乘法计算后,再相加

又或是先计算三个乘法,把前两个结果相加后得到的结果,再和第三个乘法结果相加

如果是变量值还好,但假设是表达式呢,是不是会影响最终结果

2.C到底何时加

C+ ++C;

这个代码问题在于到底是什么时候加上C,是我++之后还是++之前呢?

3.逻辑混乱

int i = 10;
i = i-- - --u*(i=3)*i++ + ++i;

 第一眼你看到这个代码是不是想这个表达式到底要传达什么意思,如果你用不同编辑器去计算,会有不同结果,这个算式出自于一本书《C和指针》作者都抓狂了这个代码

感谢比特教育机构提供的图

4.fun函数究竟什么时候开始调用

int fun()
{static int count = 1;return ++ count;
}int main()
{int answer;answer = fun()-fun()*fun()
printf("%d\n",answer);
return 0;
}

##如果你把这个表达式放在VS2022中,结果就是2-3*4=-10

5.这位更是重量级

int main()
{int i = 1;int ret = (++i) + (++i)+(++i);printf("%d\n", ret);printf("%d\n", i);return 0;//VS中是12 4,而你用Dev是10 4
}

为什么是截然不同的结果

在VS中是算出三个++i之后的i的结果再把三个i相加
而在Dev中是先算出前两个++i之后,先把前两个i相加,最后再i再加1,之后再把上一次相加值加到这一次

我搞不明白为什么有的学校把这个当成期末考试题还给出选项


因此,我们不要写以上这些难看的low代码,想先算哪个加括号就好


五、内存

1.我们都知道1byte(比特)=8字节,其他都是1024进制转化

2.我们把内存划分成一个个小的空间,每一个空间都是一个字节,为一个内存单元,我们可以给内存单元编号,就是指针,就是地址

3.各个硬件之间进行数据传递,CPU与内存之间有很多“线”连接起来,一般有“地址总线”,“数据总线”,“控制总线”,我们读写都是通过这些进行的

4.CPU访问内存的时候需要知道其位置,我们就给内存编址,给每个内存单元编号(硬件设计的时候已经编好)

32位机器有32根地址总线,每根总线有0和1两张状态,攻击2的32次方中编号,64位机器择优2的64次方种编号

六、指针变量和地址(Part 1)

1.取地址操作符(&)

我们回忆下,变量创建的本质是什么,就是在内存中申请4个字节空间,以此来存储数据

例如int a =10,其中这个a不是给编译器和计算机看的,是给你看的,它们看的是地址

你可以在调试中找到监视输入取地址操作符查看变量a的地址,中间那一行是十六进制存储的,比如10=1011=啊,我们就可以看到000a

但是a它有四个字节啊,不应该有四个地址吗,如果你通过取地址操作符,你会看到是地址中较小的地址,为什么?

因为这样可以顺理成章求出其他地址,存放地址的变量就成为指针变量,如:

int *p=&a,这里的int *就为a的类型,而且指针变量是专门存放地址的,在它的眼里什么都是地址

3.解引用操作符(“*”)

int a =10;
int *p=&a;
*p=0;

我们注意区分下面两个式子区别,下面那个式子中,“*”是用来间接访问的,通过p的地址找到地址所对应的对象,这是另一种放大求变量

4.指针变量的大小

因为指针也是变量,也是需要向内存中申请空间的

我们根据地址存储大小,32位的机器通过32跟地址线传输,需要32bit=4字节空间存储

因此指针变量大小是4字节,不管你指针变量里面的数据是什么类型

统统都是4字节,而六十四位机器就是8字节 

 


作者学术不精,难免有疏漏,若有错误欢迎指出,评论区讨论


END

http://www.xdnf.cn/news/2826.html

相关文章:

  • 软考-软件设计师中级备考 7、算法设计与分析
  • 如何理解promise 续二
  • C语言学习路线
  • 国内外都有哪些医药医学方面的指南检索数据库?
  • 模电——PN结
  • TensorRT详解
  • 如何在idea中编写spark程序
  • java快速幂
  • 从传统制造到智能工厂:MES如何重塑电子制造业?
  • ship_plant船舶模型
  • QT事件Trick
  • 网络》》ARP、NAT
  • 【题解】CF2096F
  • JAVA中Spring全局异常处理@ControllerAdvice解析
  • 【前端】跟进新趋势- PWA WebAssembly
  • 医院信息管理系统全解析
  • 第六章:Tool and LLM Integration
  • DDS(数据分发服务)原理详解
  • 第三章:Configuration Management
  • 测试用例设计的完整过程详解:从需求到覆盖的实战指南
  • Python 中调用方法内部定义的类详解(类在方法中的各种操作)
  • 3、CMake语法:制作和使用动态库和静态库
  • 现代c++获取linux所有的网络接口名称
  • Java大师成长计划之第6天:Java流式API(Stream API)
  • Kubernetes基础与部署实战
  • shell(3)
  • windows中无法关闭mysql57服务
  • 深度学习近十年的汇总
  • 复习Vue136~180
  • HarmonyOS SDK助力鸿蒙版今日水印相机,真实地址防护再升级