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

大连哪家网站公司好/百度登录入口

大连哪家网站公司好,百度登录入口,网站做兼容处理怎么设置,美国网站做付款方式前言 很多编程语言的语法中都有关于声明和定义的概念,这种概念一般会应用于函数或变量的创建和使用中,但是为什么要这么做? 以C语言为例,一些书籍或教程会要求读者在程序文件开头写上函数和变量的声明,然后再在后面对…

前言

很多编程语言的语法中都有关于声明和定义的概念,这种概念一般会应用于函数或变量的创建和使用中,但是为什么要这么做?

以C语言为例,一些书籍或教程会要求读者在程序文件开头写上函数和变量的声明,然后再在后面对其进行定义(对于变量也可以叫初始化)。这不免让人感到有一丝疑惑,为什么要这样做?我能不能先定义再声明?或者我能否不声明直接定义?

事实上这样做很多时候也是可以的,但是为什么呢?

为此我们需要明确一些基本的概念。

编译和链接

以C和C++为例,如果你正在使用某个IDE进行编程,那么你应该可以发现,在你写好一个程序后需要将它运行之前,往往需要先进行构建(有的IDE里面写的是生成或build),然后经过一段时间的等待后,你就会获得一个可执行程序,之后你就可以运行这个程序文件得到想要的效果。

这个过程中发生了什么呢?一般情况下这个过程分为了三步——预处理、编译、链接。预处理过程一般是C和C++的特色,你所见到的那些带#的语句一般被称为宏,而这些宏将会被预处理器进行预处理。通常而言,你只需要知道#define(将被定义的内容用定义的内容进行替换)和#include(将被引用的文件全部原样复制到此)两个宏就够了。

不过预处理并不是我们讨论的焦点。

编译一般发生于预处理之后,一般而言,当预处理结束后,所有有用的.h文件都已经通过#include被原样复制到了.c文件中了,所以整个工程现在就只剩下一堆.c文件。而编译器会检测每个.c文件然后将它们编译称为对应的汇编文件,再然后将汇编文件翻译成二进制文件。不过一般而言,翻译成为汇编文件这个过程都是被隐藏的,至少如果不单独设置你是无法看到生成汇编文件这个过程。不过没关系,这样也可以简化我们的思路,所以直接将编译过程理解为从.c文件到二进制文件(这个文件后缀根据编译器和系统的不同可能有所差异,一般是.o.obj,当然具体是什么后缀都不重要)。

编译结束后,显然我们会得到一堆二进制文件,它们和之前写的.c文件一般是一一对应的。但是很显然,这些二进制文件还不是可执行程序,而且它们太分散了。这个时候就需要链接器进行工作,链接器会根据链接表将所有二进制文件进行重组和拼装,最后形成一个完整的可执行文件。

声明和定义

那么,声明和定义在这里有什么用呢?

为什么要声明

现在我们假设一个工程中有两个.c文件,一个是main.c,里面放了一个空的main函数,此外什么也没有。另一个是hello.c,里面放了一个void SayHello()函数并引用了stdio.h文件,这个函数的功能是输出一个Hello World

显然,hello.c里面实现了对SayHello函数的定义,也就是说我们的工程中已经实现了SayHello这个函数,此时我们是否能够在main函数中调用它呢?

如果你尝试直接在main函数中调用SayHello,然后分别对main.chello.c进行编译(一般IDE会有单独的编译选项,右键单击某个c文件就可以选择,而且这个编译事实上还是包括了预处理过程的),你会发现对main.c进行编译的时候会出现报错。

编译器会提示你,没有对SayHello函数进行定义。

但是我们明明在hello.c中进行定义了啊?难道是我需要先编译一下hello.c然后再编译main.c?事实上你换一下顺序结果也是一样。

因为编译器是没有记忆的,当他编译完一个文件,就会马上忘记它在这个文件里都发现了什么东西,所以哪怕它刚刚才在hello.c里面编译了SayHello的定义,但是现在它在编译main.c,它就已经忘记了这回事了。

那么我们有什么办法可以解决这种情况呢?

第一种方法就是,在main.c的前面加上对SayHello的定义,注意尤其一定要在main函数的前面。有人会问,为什么一定要在前面,后面不行吗?事实上确实不行,因为当编译器发现一个它从来没见过的函数调用时,就会马上报错,不会那么智能地再在后面找一遍你是不是定义在后面了,所以唯有在调用之前就定义好,他才知道你有好好定义这个函数,然后它就不会闹了。

但是显然,如果我希望在多个文件里面调用SayHello函数,那么这个方法就不起效了。

所以我们就有了第二种方法,在main.c文件前面加上一句对SayHello的声明。声明只需要写上函数返回值、函数名和函数参数表就可以了,不需要写完整的实现。声明其实是程序员对编译器的保证,意思就是“我保证我在其它某个地方肯定会写这个函数的定义的”,然后编译器会相信程序员,虽然你并没有实际在这个文件中定义这个函数,但是当你调用这个函数的时候,编译器不会报错。注意,声明也需要写在调用的前面,逻辑和第一种方法一样。

现在你大概理解了声明的意思了,而一般情况下,声明会被写在一个.h文件中,要使用某个函数之前只要#include这个文件并且将它对应的.c文件包含在工程内即可。

注意,除了#include,你一定也要将它对应的.c文件包含在工程内,因为.c文件里包含了对这些函数的定义。

为什么要定义

没有定义显然是不行的,否则这个函数就是一个空有名字和输入输出的不明物,很显然这是程序员的疏忽(或像我们故意)造成的错误,是需要被发现检测出来的。

现在,我们做个简单的小实验,还是刚才的工程,但是我们将hello.c里的SayHello注释掉(如果你不怕麻烦想要更好的体验,可以直接删掉hello.c或将它移出工程),此时我们再次编译hello.cmain.c,你会发现,编译器仍然没有报错。

是不是有点疑惑,现在明显没有SayHello的定义,但是为什么编译器不报错呢?

很显然,是因为编译器非常相信你,你在main.c中声明了,你一定会定义SayHello的,所以编译器就理所当然地相信了你,而没有记忆的它显然是无法发现自己被骗了。而hello.c文件里什么都没有,那么自然也不会有什么错(如果你直接将其移除了工程就更加不可能报错了)。

但是这并不代表你能一直骗它,我们知道编译结束后还得链接才能得到可执行程序,不过IDE一般没有单独的链接按钮,所以我们得使用构建,当按下这个按钮后整个工程都将完整经历完前面说的三个过程——预处理、编译和链接。其中预处理和编译仍然是刚才我们的编译器进行的,它和刚才一样,没有发现任何问题。

但是你骗不了链接器,因为它会对程序进行重新组装,但是在组装的过程中它会发现,有一个本来应该出现的函数定义却在此刻不见了,然后它会发出一个L字母开头的报错,唯有你在工程中重新创建了这个函数的定义并重新构建才可以消除。

总结

这里用C语言的函数声明与定义解释了为什么要声明和定义以及它们有什么用,用相同的逻辑它也可以扩展到变量以及其它语言的声明与定义中。

相关文章:

声明和定义

前言 很多编程语言的语法中都有关于声明和定义的概念,这种概念一般会应用于函数或变量的创建和使用中,但是为什么要这么做? 以C语言为例,一些书籍或教程会要求读者在程序文件开头写上函数和变量的声明,然后再在后面对…...

Python获取最小路径,查找元素在list中的坐标

# codingutf-8__author__ Jeff.xiedef t(li):pass获取最小路径def minPathSum(grid):if not grid:return 0m len(grid) #m列n len(grid[0]) #n行print(grid[0])print("m: ",m)print("n: ",n)#创建一个二维数组dp [[0]*n for _ in range(m)]print(dp) #这…...

数据采集协同架构,集成马扎克、西门子、海德汉、广数、凯恩帝、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科、华中各类数控以及各类PLC数据采集软件

文章目录 前言一、采集协同架构是什么?可以做什么(数控、PLC配置采集)?二、使用步骤 1.打开软件,配置MQTT或者数据库(支持sqlserver、mysql等)存储转发消息规则2.配置数控系统所采集的参数、转…...

Allegro172版本如何用自带的功能实现快速在1MMBGA下方等距放置电容

Allegro172版本如何用自带的功能实现快速在1MMBGA下方等距放置电容 在做PCB设计的时候,在1MM中心间距的BGA背面放置电容,是非常常见的设计,如何快速把电容等距放在BGA下方,除了借助辅助工具外,在Allegro升级到了172版本的时候,可以借助本身自带的功能实现快速放置,以下图…...

一种简单的统计pytorch模型参数量的方法

nelememt()函数Tensor.nelement()->引自Tensor.numel()->引自torch.numel(input)三者的作用是相同的Returns the total number of elements in the inputtensor.返回当前tensor的元素数量利用上面的函数刚好可以统计模型的参数数量parameters()函数Module.parameters(rec…...

【PyTorch】教程:对抗学习实例生成

ADVERSARIAL EXAMPLE GENERATION 研究推动 ML 模型变得更快、更准、更高效。设计和模型的安全性和鲁棒性经常被忽视,尤其是面对那些想愚弄模型故意对抗时。 本教程将提供您对 ML 模型的安全漏洞的认识,并将深入了解对抗性机器学习这一热门话题。在图像…...

中国区使用Open AI账号试用Chat GPT指南

最近推出强大的ChatGPT功能,各大程序员使用后发出感叹:程序员要失业了 不过在国内并不支持OpenAI账号注册,多数会提示: OpenAI’s services are not available in your country. 经过一番搜索后,发现如下方案可以完…...

STM32开发(9)----CubeMX配置外部中断

CubeMX配置外部中断前言一、什么是中断1.STM32中断架构体系2.外部中断/事件控制器(EXTI)3.嵌套向量中断控制器(NIVC)二、实验过程1.CubeMX配置2.代码实现3.硬件连接4.实验结果总结前言 本章介绍使用STM32CubeMX对引脚的外部中断进…...

Nextjs了解内容

目录Next.jsnext.js的实现1,nextjs初始化2, 项目结构3, 数据注入getInitialPropsgetServerSidePropsgetStaticProps客户端注入3,CSS Modules4,layout组件5,文件式路由6,BFF层的文件式路由7&…...

从事功能测试1年,裸辞1个月,找不到工作的“我”怎么办?

做功能测试一年多了裸辞职一个月了,大部分公司都要求有自动化测试经验,可是哪来的自动化测试呢? 我要是简历上写了吧又有欺诈性,不写他们给的招聘又要自动化优先,将项目带向自动化不是一个容易的事情,很多…...

机器学习基本原理总结

本文大部分内容参考《深度学习》书籍,从中抽取重要的知识点,并对部分概念和原理加以自己的总结,适合当作原书的补充资料阅读,也可当作快速阅览机器学习原理基础知识的参考资料。 前言 深度学习是机器学习的一个特定分支。我们要想…...

JVET-AC0315:用于色度帧内预测的跨分量Merge模式

ECM采用了许多跨分量的预测(Cross-componentprediction,CCP)模式,包括跨分量包括跨分量线性模型(CCLM)、卷积跨分量模型(CCCM)和梯度线性模型(GLM)&#xff0…...

Session与Cookie的区别(二)

脸盲症的困扰 小明身为杂货店的店长兼唯一的店员,所有大小事都是他一个人在处理。传统杂货店跟便利商店最大的差别在哪里?在于人情味。 就像是你去菜市场买菜的时候会被说帅哥或美女,或者是去买早餐的时候老板会问你:「一样&#…...

疫情开发,软件测试行情趋势是怎么样的?

如果说,2022年对于全世界来说,都是一场极大的挑战的话;那么,2023年绝对是机遇多多的一年。众所周知,随着疫情在全球范围内逐步得到控制,无论是国际还是国内的环境,都会呈现逐步回升的趋势&#…...

Java中间件描述与使用,面试可以用

myCat 用于切分mysql数据库(为什么要切分:当数据量过大时,mysql查询效率变低) ActiveMQ 订阅,消息推送 swagger 前后端分离,后台接口调式 dubbo 阿里的面向服务RPC框架,为什么要面向服务&#x…...

[OpenMMLab]AI实战营第七节课

语义分割代码实战教学 HRNet 高分辨率神经网络 安装配置 # 选择分支 git branch -a git switch 3.x # 配置环境 conda create -n mmsegmentation python3.8 conda activate mmsegmentation pip install torch1.11.0cu113 torchvision0.12.0cu113 torchaudio0.11.0 --extra-i…...

面向对象的设计模式

"万丈高楼平地起,7种模式打地基",模式是一种规范,我们应该站在巨人的肩膀上越看越远,接下来,让我们去仔细了解了解面向对象的7种设计模式7种设计模式设计原则的核心思想:找出应用中可能需要变化之…...

里氏替换原则|SOLID as a rock

文章目录 意图动机:违反里氏替换原则解决方案:C++中里氏替换原则的例子里氏替换原则的优点1、可兼容性2、类型安全3、可维护性在C++中用好LSP的标准费几句话本文是关于 SOLID as Rock 设计原则系列的五部分中的第三部分。 SOLID 设计原则侧重于开发 易于维护、可重用和可扩展…...

【C++】右左法则,指针、函数与数组

右左法则——判断复杂的声明对于一个复杂的声明,可以用右左法则判断它是个什么东西:1.先找到变量名称2.从变量名往右看一个部分,再看变量名左边的一个部分3.有小括号先看小括号里面的,一层一层往外看4.先看到的东西优先级大&#…...

打通数据价值链,百分点数据科学基础平台实现数据到决策的价值转换 | 爱分析调研

随着企业数据规模的大幅增长,如何利用数据、充分挖掘数据价值,服务于企业经营管理成为当下企业数字化转型的关键。 如何挖掘数据价值?企业需要一步步完成数据价值链条的多个环节,如数据集成、数据治理、数据建模、数据分析、数据…...

C++之多态【详细总结】

前言 想必大家都知道面向对象的三大特征:封装,继承,多态。封装的本质是:对外暴露必要的接口,但内部的具体实现细节和部分的核心接口对外是不可见的,仅对外开放必要功能性接口。继承的本质是为了复用&#x…...

ThingsBoard-RPC

1、使用 RPC 功能 ThingsBoard 允许您将远程过程调用 (RPC) 从服务器端应用程序发送到设备,反之亦然。基本上,此功能允许您向/从设备发送命令并接收命令执行的结果。本指南涵盖 ThingsBoard RPC 功能。阅读本指南后,您将熟悉以下主题: RPC 类型;基本 RPC 用例;RPC 客户端…...

java分治算法

分治算法介绍 分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或 相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题 的解的合并。这个技…...

【Flutter】【Unity】使用 Flutter + Unity 构建(AR 体验工具包)

使用 Flutter Unity 构建(AR 体验工具包)【翻译】 原文:https://medium.com/potato/building-with-flutter-unity-ar-experience-toolkit-6aaf17dbb725 由于屡获殊荣的独立动画工作室 Aardman 与讲故事的风险投资公司 Fictioneers&#x…...

MC0108白给-MC0109新河妇荡杯

MC0108白给 小码哥和小码妹在玩一个游戏,初始小码哥拥有 x的金钱,小码妹拥有 y的金钱。 虽然他们不在同一个队伍中,但他们仍然可以通过游戏的货币系统进行交易,通过互相帮助以达到共赢的目的。具体来说,在每一回合&a…...

求职(JAVA程序员的面试自我介绍)

背景 在找工作的过程中,在面试的环节,大多数面试官首先都会叫你自我介绍一下。一般是3到5分钟内。不过经过我面试的无数的公司还有曾经也面试过大多数的求职者。国内很多的程序员面试都极其不专业。有一种很随心所欲的感觉。所以经常遇到求职者吐槽遇到了…...

金三银四季节前端面试题复习来了

vue3和vue2的区别有哪些 Diff算法的改进Tree Sharing优化主要的API双向绑定改为es6的proxy原生支持tscomposition API移除令人头疼的this 说说CSS选择器以及这些选择器的优先级 !important 内联样式(1000) ID选择器(0100) 类选…...

【C/C++基础练习题】简单语法使用练习题

🍉内容专栏:【C/C要打好基础啊】 🍉本文内容:简单语法使用练习题(复习之前写过的实验报告) 🍉本文作者:Melon西西 🍉发布时间 :2023.2.10 目录 1、输入三个数…...

堆排序

章节目录:一、相关概述1.1 基本介绍1.2 排序思想二、基本应用2.1 步骤说明2.2 代码示例三、结束语一、相关概述 1.1 基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序。它的最坏最好平均时间复杂度均为 O(nlogn)&#x…...

PLC是什么?PLC相关知识小科普

欢迎各位来到东用知识小课堂1.PLC是什么:●PLC就是可编程控制器,它应用于工业环境,必须具有很强的抗干扰能力、广泛的适应能力和应用范围。●PLC是“数字运算操作的电子系统”,也是一种计算机,它是“专为在工业环境下应…...