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

硅基计划 学习总结 拾


一、结构成员

##引子##

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

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

相关文章:

  • 在 cmd shell 中执行 metasploit vbs payload
  • SpringBoot自动配置
  • 【UserDetailsService】
  • [Windows] MousePlus 5.5.9
  • 软考-软件设计师中级备考 4、数据结构
  • 关于 【Spring Boot Configuration Annotation Processor 未配置问题】 的详细分析、解决方案及代码示例
  • 【“星瑞” O6 评测】 — CPU llama.cpp不同优化速度对比
  • 数据结构算法竞赛训练网站OJ(Online Judge)
  • SDC命令详解:使用get_clocks命令进行查询
  • 【Java】 使用 HTTP 响应状态码定义web系统返回码
  • iView Table 组件跨页选择功能实现文档
  • vLLM技术解析:大语言模型推理服务的性能革新引擎
  • 算法相关概念
  • 【LLM开发】Unigram算法
  • 解密面试高频题:加权轮询负载均衡算法 (Java 实现)
  • 位运算题目:两数相除
  • 测试基础笔记第十五天
  • AI日报 - 2025年04月29日
  • esm使用-包括esmfold和embedding
  • 阿里开源图生动画模型AnimateAnyone2
  • 比熬夜更伤肝的事,你可能每天都在做
  • 贸促会答澎湃:5月22日将举办2025年贸易投资促进峰会
  • 第二十届中国电影华表奖揭晓!完整获奖名单来了
  • 加拿大警方:已确认有9人在温哥华驾车撞人事件中遇难
  • 美国政府将暂时恢复部分受影响留学生的合法身份,并将制订新标准
  • 子公司神州信息十年来首次亏损,神州控股遭国有股东广州城投派驻董事问责