C语言进阶-1
1、数据类型
1.1、基本数据类型
数据类型分2类:基本数据类型+复合类型
基本类型:char short int long float double
复合类型:数组 结构体 共用体 类(C语言没有类,C++有)
1.1.1、内存占用与sizeof运算符
数据类型就好像一个一个的模子,这个模子实例化出C语言的变量。变量存储在内存中,需要占用一定的内存空间。一个变量占用多少空间是由变量的数据类型决定的。
每种数据类型,在不同的机器平台上占用内存是不同的。我们一般讲的时候都是以32位CPU为默认硬件平台来描述:
char 1字节 8位
short 2字节 16位
int 4字节 32位
long 4字节 32位
float 4字节
double 8字节
1.1.2、有符号数和无符号数
对于char short int long等整形类型的数,都分有符号有无符号数。
而对于float和double这种浮点型数来说,只有有符号数,没有无符号数。
对于C语言来说,数(也就是变量)是存储在内存中一个一个的格子中的。存储的时候是以二进制方式存储的。对于有符号数和无符号数来说,存储方式是不同的。
unsigned int 无符号数,32位(4字节)全部用来存数的内容 所以表示的数的范围是0 ~ 4294967295(2^32 - 1)。
signed int 有符号数,32位中最高位用来存符号(0表示正数,1表示负数),剩余的31位用来存数据。所以可以表示的数的范围是 -2147483648(2^32) ~ 2147483647(2^31 - 1)。
结论:从绝对数值来说,无符号数所表示的范围要大一些。因为有符号数使用1个二进制位来表示正负号。
1.1.3、整形数和浮点型数存储方式上的不同
对于float和double这种浮点类型的数,它在内存中的存储方式和整形数不一样。所以float和int相比,虽然都是4字节,但是在内存中存储的方式完全不同。所以同一个4字节的内存,如果存储时是按照int存放的,取的时候一定要按照int型方式去取。如果存的时候和取的时候理解的方式不同,那数据就完全错了。
备注:详细的数制存储可以查找资料:计算机原码、反码、补码等知识。
总结:存取方式上主要有两种,一种是整形一种是浮点型,这两种存取方式完全不同,没有任何关联,所以是绝对不能随意改变一个变量的存取方式。
1.2、空类型(关键字void)
C语言中的void类型,代表任意类型,而不是空的意思。任意类型的意思不是说想变成谁就变成谁,而是说它的类型是未知的,是还没指定的。
void * 是void类型的指针。void类型的指针的含义是:这是一个指针变量,该指针指向一个void类型的数。void类型的数就是说这个数有可能是int,也有可能是float,也有可能是个结构体,哪种类型都有可能,只是我当前不知道。
void型指针的作用就是,程序不知道那个变量的类型,但是程序员自己心里知道。程序员如何知道?当时给这个变量赋值的时候是什么类型,现在取的时候就还是什么类型。这些类型对不对,能否兼容,完全由程序员自己负责。编译器看到void就没办法帮你做类型检查了。
在函数的参数列表和返回值中,void代表的含义是:一个函数形参列表为void,表示这个函数调用时不需要给它传参。返回值类型是void,表示这个函数不会返回一个有意义的返回值。所以调用者也不要想着去使用该返回值。
1.3、数据类型转换
C语言中有各种数据类型,写程序时需要定义各种类型的变量。这些变量需要参与运算。C语言有一个基本要求就是:不同类型的变量是不能直接运算的。也就是说,int和float类型的变量不能直接加减等运算。你要运算,必须先把两种类型转成相同的类型才可以。
1.3.1、隐式转换
隐式转换就是自动转换,是C语言默认会进行的,不用程序员干涉。当编译器发现a+b中a和b的类型不同时。这时候两个要加,编译器会进行隐式类型转换把两个转成类型相同。根据隐式类型转换的规则,编译器构造了一个临时变量(例如叫 float f1)然后把f1赋值为a转成float类型的值,之后参与运算时是用f1去和b相加的,加完之后得到一个临时变量(例如叫float f2).这个临时变量再参与之后的运算。
C语言的理念:隐式类型转换默认朝精度更高、范围更大的方向转换。赋值时必须以 = 左边的类型为准。
1.3.2、强制类型转换
C语言默认不会这么做,但是程序员我想这么做,所以我强制这么做了。
1.4、C语言与bool类型
C语言中原生类型没有bool,C++中有。在C语言中如果需要使用bool类型,可以用int来代替。很多代码体系中,用以下宏定义来定义真和假:
#define TRUE 1
#define FALSE 0
2、变量和常量
2.1、变量
变量,指的是在程序运行过程中,可以通过代码使它的值改变的量。
int g_a; // g_a定义在函数外面,因此是全局变量int main(void)
{int a; // a定义在main函数中,所以是局部变量return 0;
}
2.1.1、局部变量
定义在函数中的变量,就叫局部变量。
2.1.1.1、普通局部变量(auto)
普通的局部变量定义时直接定义,或者在定义前加auto关键字。
#include <stdio.h>void func1(void); //声明函数int main(void)
{func1(); // i = 2func1(); // i = 2func1(); // i = 2return 0;
}void func1(void)
{int i = 1; // 普通的局部变量,auto可以省略的//auto int i = 0; // 自动局部变量,其实就是普通局部变量i++;printf("i = %d.\n", i);
}
局部变量i的解析:
在连续三次调用func1中,每次调用时,在进入函数func1后都会创造一个新的变量i,并且给它赋初值1,然后i++时加到2,然后printf输出时输出2.然后func1本次调用结束,结束时同时杀死本次创造的这个i。这就是局部变量i的整个生命周期。下次再调用该函数func1时,又会重新创造一个i,经历整个程序运算,最终在函数运行完退出时再次被杀死。
2.1.1.2、静态局部变量(static)
静态局部变量定义时前面加static关键字。
#include <stdio.h>void func_static(void); //声明函数int main(void)
{func_static(); // i = 2func_static(); // i = 3func_static(); // i = 4return 0;
}void func_static(void)
{static int i = 1; // 静态的局部变量i++;printf("i = %d.\n", i);
}
2.1.1.3、静态局部变量和普通局部变量对比
1、静态局部变量和普通局部变量不同。静态局部变量也是定义在函数内部的,静态局部变量定义时前面要加static关键字来标识,静态局部变量所在的函数在多调用多次时,只有第一次才经历变量定义和初始化,以后多次在调用时不再定义和初始化,而是维持之前上一次调用时执行后这个变量的值。本次接着来使用。
2、静态局部变量在第一次函数被调用时创造并初始化,但在函数退出时它不死亡,而是保持其值等待函数下一次被调用。下次调用时不再重新创造和初始化该变量,而是直接用上一次留下的值为基础来进行操作。
3、静态局部变量的这种特性,和全局变量非常类似。它们的相同点是都创造和初始化一次,以后调用时值保持上次的不变。不同点在于作用域不同。
2.1.1.4、register关键字
register(寄存器),C语言的一个关键字
register int i = 3;
总结:
register类型的局部变量表现上和auto是一样的,这东西基本没用,知道就可以了。register被称为:C语言中最快的变量。C语言的运行时环境承诺,会尽量将register类型的变量放到寄存器中去运行(普通的变量是在内存中),所以register类型的变量访问速度会快很多。但是它是有限制的:首先寄存器数目是有限的,所以register类型的变量不能太多;其次register类型变量在数据类型上有限制,例如你就不能定义double类型的register变量。一般只在内核或者启动代码中,需要反复使用同一个变量这种情况下才会使用register类型变量。
2.1.2、全局变量
定义在函数外面的变量,就叫全局变量。
main函数是一个程序运行最开始执行的东西,所有的其他函数都只能在main函数中被直接或者间接的调用才能被执行。main函数的执行其实就是整个程序的生命周期,main函数一return返回,整个程序就结束了。
全局变量的定义和初始化就是在main函数运行之前发生的。
2.1.2.1、普通全局变量
普通全局变量就是平时使用的,定义前不加任何修饰词。普通全局变量可以在各个文件中使
用,可以在项目内别的.c文件中被看到,所以要确保不能重名。
2.1.2.2、静态全局变量
静态全局变量就是用来解决重名问题的。静态全局变量定义时在定义前加static关键字,告诉编译器这个变量只在当前本文件内使用,在别的文件中绝对不会使用。这样就不用担心重名问题。所以静态的全局变量就用在我定义这个全局变量并不是为了给别的文件使用,本来就是给我这个文件自己使用的。
2.1.2.3、跨文件引用全局变量(extern)
就是说,你在一个程序的多个.c源文件中,可以在一个.c文件中定义全局变量g_a,并且可以在别的另一个.c文件中引用该变量g_a(引用前要声明)。
函数和全局变量在C语言中可以跨文件引用,也就是说他们的连接范围是全局的,具有文件连接属性,总之意思就是全局变量和函数是可以跨文件看到的(直接影响就是,我在a.c和b.c中各自定义了一个函数func,名字相同但是内容不同,编译报错。)。
2.1.2.4、全局变量的特点
在整个文件中所有的函数内都可以访问该全局变量,而且访问的都是该全局变量本身。如果你在之前某个函数中更改了它的值,则后面再引用时它的值就是前面那次更改之后的值。
2.1.3、局部变量和全局变量的对比
1、定义同时没有初始化,则局部变量的值是随机的,而全局变量的值是默认为0。
2、使用范围上:全局变量具有文件作用域,而局部变量只有代码块作用域。
3、生命周期上:全局变量是在程序开始运行之前的初始化阶段就诞生,到整个程序结束退出的时候才死亡;而局部变量在进入局部变量所在的代码块时诞生,在该代码块退出的时候死亡。
4、变量分配位置:全局变量分配在数据段上,而局部变量分配在栈上。
注意:
判断一个变量能不能使用,有没有定义,必须注意两点:第一,该变量定义的作用域是否在当前有效,是否包含当前位置;第二,变量必须先定义后使用。所以变量引用一定要在变量定义之前。
基本概念:
作用域:起作用的区域,也就是可以工作的范围。
代码块:所谓代码块,就是用{}括起来的一段代码。
数据段:数据段存的是数,像全局变量就是存在数据段的
代码段:存的是程序代码,一般是只读的。
栈(stack):先进后出。C语言中局部变量就分配在栈中。栈是C语言对内存的管理方式。
2.2、常量
常量,程序运行过程中不会被改变的量。常量的值在程序运行之前初始化的时候给定一次,以后都不会变了,以后一直是这个值。
2.2.1、#define定义的常量
#define N 20 // 符号常量
int a[N];
2.2.2、const关键字
const int i = 14
//const和指针结合,共有4种形式
const int *p; //p是一个指针,指针指向一个int型数据。p所指向的是个常量。
int const *p; //p是一个指针,指针指向一个int型数据。p所指向的是个常量。
int *const p; //p是一个指针,指针指向一个int型数据。p本身是常量,p所指向的是个变量
const int *const p; //p是一个指针,指针指向一个int型数据。p本身是常量,指向的也是常量
结论和记忆方法:
1、const在*前面,就表示const作用于p所指向的量。所以这时候p所指向的是个常量。
2、const在*后面,表示p本身是常量,但是p指向的不一定是常量。
const型指针有什么用?
//字符串处理函数strcpy,它的函数功能是把src指向的字符串,拷贝到dst中。
char *strcpy(char *dst, const char *src);
2.2.3、枚举常量
枚举常量是宏定义的一种替代品,在某些情况下会比宏定义好用。
关键字:enum
相关文章:
C语言进阶-1
1、数据类型 1.1、基本数据类型 数据类型分2类:基本数据类型复合类型 基本类型:char short int long float double 复合类型:数组 结构体 共用体 类(C语言没有类,C有) 1.1.1、内存占用与sizeof运算符 数据…...
Python如何正确解决爬虫过程中的Cookie失效问题?
前言 本文是该专栏的第54篇,后面会持续分享python爬虫干货知识,记得关注。 在python爬虫项目中,Cookie是一种用于在客户端和服务器之间传递信息的技术。在爬取某些网站的时候,可能会需要登录才能正常获取到数据,这个时候就需要用到cookie来解决。通常情况下,需要将cooki…...
维护自己电脑浅析
作为一名计算机用户,维护自己的电脑是非常重要的,这可以保证电脑的正常运行、数据的安全、提高电脑的性能等。在本文中,我将分享一些我个人维护电脑的经验和技巧。 定期清理电脑 电脑在使用过程中会产生大量的临时文件、垃圾文件、缓存文件等…...
svo2论文
论文题目 SVO: Semidirect Visual Odometry for Monocular and Multicamera Systems 内容 1) 具有最小特征漂移的长特征轨迹; 2) 图像平面中的大量均匀分布的特征; 3)新特征与旧地标的可靠关联(即环路闭…...
【GoLang】MAC安装Go语言环境
小试牛刀 首先安装VScode软件 或者pycharmmac安装brew软件 brew install go 报了一个错误 不提供这个支持 重新brew install go 之后又重新brew reinstall go 使用go version 可以看到go 的版本 使用go env 可以看到go安装后的配置 配置一个环境变量 vim ~/.zshrc, # bre…...
epoll服务器创建
驱动 #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/io.h> #include <linux/device.h> #include <linux/uaccess.h> #include <linux/poll.h> unsigned int major; char kbuf[128]{0}…...
jdk11环境 提示“因为 accessExternalDTD 属性设置的限制导致不允许 ‘http‘ 访问“bug
在运行mybatis源码的时候,提示一下错误: Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### Cause: org.apache.ibatis.builder.BuilderException: Error creating docum…...
Android Studio 的版本控制Git
Android Studio 的版本控制Git。 Git 是最流行的版本控制工具,本文介绍其在安卓开发环境Android Studio下的使用。 本文参考链接是:https://learntodroid.com/how-to-use-git-and-github-in-android-studio/ 一:Android Studio 中设置Git …...
一个 SpringBoot 项目能处理多少请求
首先,这个问题有坑,因为 spring boot 不处理请求,只是把现有的开源组件打包后进行了版本适配、预定义了一些开源组件的配置通过代码的方式进行自动装配进行简化开发。这是 spring boot 的价值。 使用 spring boot 进行开发相对于之前写配置文…...
Python中的r字符串前缀及其用法详解
Python中的r字符串前缀及其用法详解 1. 介绍 1.1 什么是r字符串前缀 在Python中,r字符串前缀是一种特殊的字符串前缀,用于表示原始字符串。当一个字符串以r前缀开始时,它将被视为原始字符串,其中的转义字符将被忽略。 1.2 r字…...
LabVIEW实现三相异步电机磁通模型
LabVIEW实现三相异步电机磁通模型 三相异步电动机由于经济和出色的机电坚固性而广泛用于工业化应用。这台机器的设计和驱动非常简单,但在控制扭矩和速度方面,它隐藏了相当大的功能复杂性。通过数学建模,可以理解机器动力学。 基于微分方程的…...
读书会-《影响力》
《影响力》这本书的作者罗伯特西奥迪尼时全球知名说服力研究权威。因其在影响力研究领域的开创性,人们将其称为“影响力研究领域的本杰明富兰克林”。这本书从人们的心理状态,进行了很多实验研究,总结出了7大规律。如果从事营销,需…...
141. 环形链表
简单 1.9K 相关企业 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…...
学习笔记|大模型优质Prompt开发与应用课(二)|第一节:大模型应用密码—Prompt的一千种打开方式
文章目录 第一节:大模型应用密码—Prompt的一千种打开方式01你可能听过一个小故事1910华盛顿纺织厂罢工事件 02 小问题:哪些场景会被提效类目一︰减少重复性工作的成本(降本)例如∶做策划初稿、写JD、润色文案prompt生成结果prompt生成结果prompt生成结果promptprom…...
QT chart进行画图
说明 QT Chart 是一个用于在 Qt 应用程序中绘制图表的开源库。它提供了多种类型的图表,如线图、柱状图、饼图等,可以用于可视化数据和统计信息。QT Chart 是一个基于 Qt 绘图框架的扩展,可以轻松集成到现有的 Qt 应用程序中。 使用 QT Chart,你可以通过简单的代码来创建和…...
Web3将自己写在合约中的代币添加到MetaMask中管理
上文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 带着大家在智能合约中创建了一个自己的代币系统 我们可以在MetaMask中去导入 ganache环境下模拟出来的第一和第二个账号 我们这里 可以看到他们的 ETH 但看不到自己的代币符号 没关系 我们点击这下面的…...
【微信小程序】显示自带的弹窗,包括加载中,成功,错误,提示,警告
在微信小程序中,可以使用以下方法来显示自带的弹窗: 显示加载中的弹窗: wx.showLoading({title: 加载中,mask: true });显示成功的弹窗: wx.showToast({title: 成功,icon: success,duration: 2000 });显示错误的弹窗࿱…...
vue-element-plus-admin框架的tag上下文切换bug
问题 首先贴上该框架的链接:https://github.com/kailong321200875/vue-element-plus-admin 在对路由进行部分修改后,网站多次切换tag时,控制台会出现报错:Cannot read properties of undefined (reading offsetLeft)。 我在框架…...
vue中,父子组件传递参数 props 实现方式
通过 Prop 向子组件传递数据 001:父组件》子组件通信 <template><div><h1>这里是父元素</h1>//******<childComponent :detailMes"detailMes"/></div> </template><script>import childComponent from…...
Unity如何快速接入iOS和GooglePlay的成就排行榜等GameCenter功能
一般在游戏开发中,经常有成就排行榜的需求,按照我们的理解,通常是要自己导入谷歌的sdk,或者苹果的sdk,然后封装后通过桥接来调用。 不用这么复杂,本鱼蛋(egostudio 防爬)告诉大家一个方法,其实…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
