初识C语言(四)
目录
前言
十一、常见关键字(补充)
(1)register —寄存器
(2)typedef类型重命名
(3)static静态的
1、修饰局部变量
2、修饰全局变量
3、修饰函数
十二、#define定义常量和宏
十三、指针
总结
前言
上一篇文章介绍了函数,数组,操作符,常见关键字和操作符,今天再从一些关键字开始,介绍以后的内容。
十一、常见关键字(补充)
(1)register —寄存器
计算机上的数据存储到哪里呢,硬盘和内存可以存储,寄存器也可以存储,而在内存和寄存器之间还有个高速缓存也可以进行存储。
现在基本上有这几种存储,而它们的内存单位为:
网盘,上线就送几T哈哈,一般为都以T为单位,而硬盘是520G,以G为单位,内存8G/16G,以G为单位,高速缓存以xxM,以M为单位,而寄存器则以字节为单位,这些大小的单位是可以用价格进行比较的,这一看网盘就便宜,寄存器最贵,为什么内存小了而价格会贵?因为它的速度非常快,越快越贵。速度越快造价就越高空间就越小。寄存器是集成到cpu(中央处理器)上的,它跟内存没有关系,也是一种独立的空间。
(2)typedef类型重命名
typedef unsigned int uint;
int main( )
{unsigned int age;uint age2;return 0;
}
顾名思义,类型重命名,上面的代码如果我们想要一个 无符号整形,那么就可以用typedef,这里面的意思就是用一个uint的新名称来重新命名unsigned int,之前要定义一个变量要在前面写unsigned int,而当用uint重命名之后,就可以用uint+类型名来定义,以后uint就代表unsigned int,所以非常方便,以后一些复杂的变量类型都可以用typedef来重新命名,改的时候也好改,只要改一句就可以。不需要都改,那样非常麻烦。
(3)static静态的
有三种用法:
1、修饰局部变量
2.修饰全局变量
3.修饰函数
1、修饰局部变量
void test( )
{int a =0;a++;printf("%d\n",a);
}int main( )
{int i =0;while(i<10){test( );i++;}return 0;
}
这里的程序是打印十个1, while循环从0开始,内部进行test函数,而test函数创建了a=0这个变量,a加1,打印1,i+1,而a这个变量作用域生命周期结束,进行销毁,这样运行十次,所以就打印十个1。
void test( )
{static int a =0;a++;printf("%d\n",a);
}
而当我们在变量a前面加上一个static关键字,那么结果就会发生变化,结果会从1到10依次输出, while循环从0开始,内部进行test函数,而test函数创建了a=0这个变量,a加1,打印1,而出test这个函数的时候,变量a不会销毁,a就会依次增加,才会输出1到10。
内存一般分为栈区,堆区和静态区,栈区一般都是存放一些局部变量,函数参数以及一些临时的变量,而堆区一般是动态内存分配,malloc,calloc,realloc,free等,而静态区是存放静态变量以及全局变量,放在栈区的是进入作用域创建,出了作用域销毁释放,下一次进来的时候就要重新创建;静态区里的数据创建后直到程序结束了之后才会释放,所以下一次进来的时候并不会重新创建,因为之前的值没有被销毁回收。
局部变量被static修饰后,这种变量就放在了静态区,放在静态区的变量,创建好后直到程序结束后才释放,本质上是static的修饰改变了局部变量的存储位置,由于存储位置的差异,执行效果就会发生差异,而且被static修饰是不影响作用域的,但是声明周期发生了变化,可以说是变长了。
2、修饰全局变量
//第一个文件
int a = 2024;//第二个文件extern int a;
int main( )
{printf("%d\n",a);return 0;
}
在源文件里面写两个C文件,在第一个文件中定义全局变量a为2024,在第二个文件中通过声明外部符号来声明a,从而调用a的值,打印出a的值,毋庸置疑,这里打印出来的就是2024。
//第一个文件
static int a = 2024;//第二个文件extern int a;
int main( )
{printf("%d\n",a);return 0;
}
而当在定义全局变量a的时候,在前面加上static静态关键字,就会发现这里面会报错,编译器会说无法解析外部符号a,无法解析外部命令。
之前是普通的全局变量,因为全局变量是具有外部链接属性的(局部变量是无链接属性的),所以第二个文件可以通过链接来使用a,但是如果全局变量被static修饰,这个外部链接属性就变成了内部链接属性,这个全局变量就只能在自己所在的源文件内部使用。
a一旦加上static,就只能在它所在的文件内使用,就像限制了它的使用范围,最终影响的是全局变量的作用域,使得全局变量的作用域变小了。
3、修饰函数
//第一个文件
int Add(int x,int y)
{return x+y;
}//第二个文件
extern int Add(int x,int y);
int main( )
{int a =10;int b =10;int c =Add(a,b);printf("%d\n",c);return 0;
}
在调用函数的时候,不同文件也要声明外部函数,从而才能运行。
//第一个文件
static int Add(int x,int y)
{return x+y;
}//第二个文件
extern int Add(int x,int y);
int main( )
{int a =10;int b =10;int c =Add(a,b);printf("%d\n",c);return 0;
}
函数本身具有外部链接属性的,被static修饰后,外部链接属性就变成了内部链接属性,就只能在函数所在的源文件内使用,使作用域变小了。这与上面的修饰全局变量的作用一样。
十二、#define定义常量和宏
C语言中很常见就是#define,我们可以用来它来定义符号或者宏,比如在下面定义一个值M,这个M的值为100,这是一个符号,同时是一个常量值,而不是常量。
#define M 100
int main( )
{printf("%d\n",M);
}
同时,define还可以进行定义宏,下面MAX就是一个宏
#define MAX(x,y) (x>y?x:y)int main( )
{int a =10;int b =20;int m =MAX(a.b);//就相当于 int m = (a>b?a:b);printf("%d\n",m);
}
但我们在主函数里面调用宏的时候,参数就会发生替换,通过宏体进行替换,从而返回值。一般宏是用来进行较为简单的处理的,函数一般则是进行复杂一些的。
十三、指针
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中间进行的,所以为了更有效的使用内存,就把内存划分为一个个小的内存单元,每个内存单元的大小为1个字节,为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
要了解指针,首先要理解内存,内存是计算机上的一种存储介质(存储空间),程序在运行中会载入内存,我们可以打开任务管理器来查看各个程序占用的内存,程序中如果需要数据存储,也会申请空间。
如何有效的使用内存,在生活中,我们的高楼也许会有几层或者几十层,如何更加高效而又准确的管理,是的,每个楼层每户人家都有一个编号,也就是门牌号,通过门牌号就可以定位家在哪里,就非常的好管理一个门牌号就对应一个房间。内存其实也参考了这个思路。
假设图中的一个大长方形就是一个内存空间,里面的一个小格子就是一个内存单元,同时给每个内存单元进行相应编号,未来通过编号就可以找到相应的定位内存单元,实践中,一个内存单元的大小是一个字节。计算机中,内存的编号也会叫做地址,地址叫做指针。
如果访问一个内存单元,那内存单元的地址(指针)如何产生:32位的机器为例,里面有32根地址线,地址线如果通电,由于电信号有高电平和低电频,转化为就是0和1,转换为数字信号,32根地址线就会产生:
00000000000000000000000000000000
00000000000000000000000000000001
........
1111111111111111111111111111111111111
32个全0到32个全1,也就一一对应内存单元,最多产生2的32次方这样的二进制序列,就可以作为2的32次方个地址,就可以管理2的32次方个内存单元,也就是2的32次方个字节的内存空间。也就是2的32次方字节,转换就是 4,294,967,296 byte,也就是4个GB的内存。内存的编号,地址,指针其实就是一个东西。
#int main( )
{int a =1;printf("%d\n",a); return 0;
}
上述代码定义了一个命名为a的常量,而它会向内存申请一个四个字节的空间,用之前的图像来说就是占用了四层小格。每一个字节都有一个自己的编号。
int main( )
{int a =1;printf("%p\n",&a);//打印a的地址return 0;
}
上述代码就打印出了a的地址,但是拿出的是a所占四个字节地址中第一个字节的地址,(&a取出的是a所占内存中4个字节中第一个字节的地址)。
当得到地址了,可以先把地址(十六进制)存到一个变量中去,将来用的时候用就可以,就类似于现实中的家庭地址一样,将来要邮快件的时候就可以通过地址来邮过去。
int a =1;
int * pa =&a;
上述创建了一个a 的变量,又通过pa来表示接收a的地址,而地址又叫指针,所以把pa叫做指针变量,指针变量是存放指针的一个变量。*说明pa是指针,int说明pa指向的是类型为整形的变量,&a说明是a的地址。
现在就可以通过pa来找到a了:
int a =1;
int * pa =&a;
* pa = 20;
*pa叫做解引用操作,作用就是通过pa中的地址找到a,*pa就是a,这就找到了a。这时候通过pa地址找到了a,同时改为20,就相当于a=20,所以a就又原来的1变为了20。通过地址改变a,并不改变pa里的任何东西。
有两种理解方式,一是指针就是地址,二是指针一般指的是指针变量,指针变量是用来存放地址的,而地址在32位机器上,是32位bit位,指针变量就是存放的是32bit的地址,一个字节8个bit,所以32位机器指针变量的大小是4个字节,在64位机器上,是64个bit位,指针大小为8个字节。
总结
指针很重要,后续会详解,介绍马上完事了,祝大家越来越牛
相关文章:

初识C语言(四)
目录 前言 十一、常见关键字(补充) (1)register —寄存器 (2)typedef类型重命名 (3)static静态的 1、修饰局部变量 2、修饰全局变量 3、修饰函数 十二、#define定义常量和宏…...

产品架构图:从概念到实践
在当今快速发展的科技时代,产品架构图已成为产品经理和设计师不可或缺的工具。它不仅帮助我们理解复杂的产品体系,还能指导我们进行有效的产品设计和开发。本文将深入探讨产品架构图的概念、重要性以及绘制方法。 整个内容框架分为三个部分,…...

smartctl 命令:查看硬盘健康状态
一、命令简介 smartctl 命令用于获取硬盘的 SMART 信息。 介绍硬盘SMART 硬盘的 SMART (Self-Monitoring, Analysis, and Reporting Technology) 技术用于监控硬盘的健康状态,并能提供一些潜在故障的预警信息。通过查看 SMART 数据,用户可以了解硬…...

BBR 为什么没有替代 CUBIC 成为 Linux 内核缺省算法
自 2017 年底 bbr 发布以来,随着媒体的宣讲,各大站点陆续部署 bbr,很多网友不禁问,bbr 这么好,为什么不替代 cubic 成为 linux 的缺省算法。仅仅因为它尚未标准化?这么好的算法又为什么没被标准化ÿ…...
Git忽略规则原理和.gitignore文件不生效的原因和解决办法
在使用Git进行版本控制时,.gitignore文件扮演着至关重要的角色。它允许我们指定哪些文件或目录应该被Git忽略,从而避免将不必要的文件(如日志文件、编译产物等)纳入版本控制中。然而,在实际使用过程中,有时…...

MySQL-数据库设计
1.范式 数据库的范式是⼀组规则。在设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数 据库,这些不同的规范要求被称为不同的范式。 关系数据库有六种范式:第⼀范式(1NF)、第⼆范式(…...

Unity开发绘画板——04.笔刷大小调节
笔刷大小调节 上面的代码中其实我们已经提供了笔刷大小的字段,即brushSize,现在只需要将该字段和界面中的Slider绑定即可,Slider值的范围我们设置为1~20 代码中只需要做如下改动: public Slider brushSizeSlider; //控制笔刷大…...
./mnt/container_run_medium.sh
#!/bin/bash# 清理旧的日志文件 rm -f *.log rm -f nohup.out rm -f cssd.dat# 启动 pwbox_simu 和 MediumBoxBase nohup /mnt/simutools/pwbox_simu /mnt/simutools/pw_box.conf > /dev/null 2>&1 & nohup /mnt/mediumSimu/MediumBoxBase /mnt/mediumSimu/hynn_…...

数学建模研赛总结
目录 前言进度问题四分析问题五分析数模论文经验分享总结 前言 本文为博主数学建模比赛第五天的内容记录,希望所写的一些内容能够对大家有所帮助,不足之处欢迎大家批评指正🤝🤝🤝 进度 今天已经是最后一天了…...
通信工程学习:什么是TCF技术控制设施
TCF(Technical Control Facility):技术控制设施 首先,需要明确的是,通信工程是一门涉及电子科学与技术、信息与通信工程和光学工程学科领域的基础理论、工程设计及系统实现技术的学科。它主要关注通信过程中的信息传输…...

stm32 bootloader跳转程序设计
文章目录 1、bootloader跳转程序设计(1)跳转程序(2)、app程序中需要注意<1>、在keil中ROM起始地址和分配的空间大小<2>、在system_stm32f4xx.c中设置VECT_TAB_OFFSET为需要偏移的地址<3>、main函数中使能中断 总…...
科技赋能环保:静电与光解技术在油烟净化中的卓越应用
我最近分析了餐饮市场的油烟净化器等产品报告,解决了餐饮业厨房油腻的难题,更加方便了在餐饮业和商业场所有需求的小伙伴们。 随着环保政策的不断升级,餐饮行业的油烟治理成为重要课题。油烟净化器的技术革新不仅提升了净化效率,…...
FCA-FineBI试卷答案
1、【判断题】FineBI数据加工建模中只支持文本、数值、日期三种数据类型。 正确答案:A A. 正确 B. 错误 2、【判断题】Excel 支持批量导入,可以一次导入多个 sheet 或 Excel? 正确答案:A A.正确 B. 错误 3、【判断题】FineBI V6.…...

Spring - @Import注解
文章目录 基本用法源码分析ConfigurationClassPostProcessorConfigurationClass SourceClassgetImportsprocessImports处理 ImportSelectorImportSelector 接口DeferredImportSelector 处理 ImportBeanDefinitionRegistrarImportBeanDefinitionRegistrar 接口 处理Configuratio…...

新能源汽车储充机器人:能源高效与智能调度
新能源汽车储充机器人:开启能源高效利用与智能调度的未来之门 随着全球能源危机的日益加剧和环境污染问题的不断恶化,新能源汽车成为了未来交通领域的重要发展方向。然而,新能源汽车的普及不仅需要解决电池技术的瓶颈,还需要构建一…...

【Linux网络】详解TCP协议(2)
🎉博主首页: 有趣的中国人 🎉专栏首页: Linux网络 🎉其它专栏: C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好,本片文章将会讲解 TCP协议的三次握手和四次挥手 的相关内容。 如果看到最后您觉得…...

STM32DMA学习日记
STM32 DMA学习日记 写于2024/9/28晚 文章目录 STM32 DMA学习日记1. DMA简介2. I/O方式2.1 程序查询方式2.2 程序中断方式2.3 DMA方式 3.DMA框图4. 相关寄存器4.1 DMA中断状态寄存器(DMA_ISR)4.2 DMA中断标志清除寄存器(DMA_IFCR)…...

【高性能内存池】page cache 5
page cache 1 page cache的框架2 central cache从page cache申请n页span的过程3 page cache 的结构3.1 page cache类框架3.2 central cache向page cache申请span3.3 获取k页的span page cache的结构和central cache是一样的,都是哈希桶的结构,并且挂载的…...

Vue 3 魔法揭秘:CSS 解析与 scoped 背后的奇幻之旅
文章目录 一、背景二、源码分析transformMain 返回值transformStyle 方法compileStyleAsync 方法scopedPlugin 方法template 添加 __scopeId 三、总结 一、背景 Vue 3 文件编译流程详解与 Babel 的使用 上文分析了 vue3 的编译过程,但是在对其中样式的解析遗留了一…...

如何获取钉钉webhook
第一步打开钉钉并登录 第二步创建团队 并且 添加自定义 机器人 即可获取webhook...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...