網站首頁 編程語言 正文
一、變量的聲明與定義
首先,舉個簡單的例子:
int a;
extern int b;
這里的兩個變量,哪個是聲明?哪個是定義?
為解決這個問題,我們必須要知道聲明與定義的含義。
聲明:聲明是用來告訴編譯器變量的名稱和類型,而不分配內存。
- 告訴編譯器,這個變量或者對象已經匹配到一塊內存空間上了,下面代碼中用到的變量或者對象會在別的地方定義,但此處并不分配內存,所以聲明可以出現多次;
- 告訴編譯器,這個名字已經被預定了,別的地方不能再用它作為變量或者對象名。這種聲明最典型的例子就是函數參數的聲明。
定義:就是編譯器為一個變量或者對象分配到一塊內存空間上,并給它取名字。這個名字就是變量名或對象名,所以同一名字的變量或者對象只能被定義一次,當多次被定義的時候,編譯器就會提示重復定義同一變量或對象的錯誤。
定義是為了給變量分配內存,可以為變量賦初值。
在上述代碼中,extern 是一個關于聲明的關鍵字,放在變量或者函數前用于聲明,用來說明”此變量或者函數在別處定義“。
注意的是:即使使用了extern,如果給變量附了值,就是定義了。
我們現在知曉了聲明和定義的含義,那么對于上面的例子,我想答案早已浮出水面。
int a; //此語句為定義
extern int b; //此語句為聲明
示例:
extern int a; //此語句為聲明
extern int b = 10; //此語句為定義
typedef int INT; //此語句為聲明
struct Node; //此語句為聲明
int c ; //此語句為定義
struct Node { //此語句為定義
int left;
int right;
};
上述代碼中,變量名c,其類型為int,配分4字節的內存空間(不同編譯器可能會有差異)。
二、函數的聲明與定義
首先,我們同樣先了解一下它們的含義
函數聲明:告訴編譯器,函數的名稱、參數類型和數量以及函數返回值的類型。
函數定義:為了給函數分配內存空間。
例如:
int Max(int x, int y); //此處聲明了一個函數,其函數名為Max,參數為int x,int y,返回類型為int
int Max(int x, int y) {return x > y ? x : y;} //此處定義了一個函數
函數的定義包含了函數的具體實現。
函數只要有實現(存在函數體{…})即為定義,否則為聲明。
注:為什么這里的函數聲明不用寫extern?函數一般是全局的,即他的可見性是最大范圍的,在別的文件也可以訪問這個函數,其實函數默認就是extern,所以可以不寫。
另外,當在函數前加static 時,則函數的作用域僅局限于本文件。
再來看一段代碼
/* basic_stdy.h */
#ifndef _BASIC_STDY_H_
#define _BASIC_STDY_H_
//extern int a; //在頭文件中聲明,必須加上extern,否則就是重定義
//void fun(); //不用加extern也可以
#endif
/* basic_stdy.cpp */
#include"basic_stdy.h"
#include<iostream>
using namespace std;
int a(2);
void fun(){
cout << a <<endl;
}
/* main.cpp */
#include<iostream>
//#include "basic_stdy.h"
using namespace std;
extern int a; //ok不用包含頭文件, 變量只要聲明即可
extern void fun(); //ok不用包含頭文件, 函數只要聲明即可
int main(int argc,char **argv){
cout << a << endl;
fun();
system("pause");
return 0;
}
上述代碼中一共有三個文件basic_stdy.h、basic_stdy.cpp和main.cpp,要在main.cpp中使用其他文件中定義的變量和函數,有以下兩種實現方式:
1、在basic_stdy.h頭文件中,聲明他們,然后在main.cpp中去包含頭文件;
2、在main.cpp中直接extern。
三、總結
- 變量或函數可以聲明多次,但變量或函數的定義只能一次;
- 聲明不會分配內存,定義會分配內存;
- 聲明是告訴編譯器變量或函數的類型、名稱等,而定義是告訴編譯器變量的值,函數的具體實現。
原文鏈接:https://blog.csdn.net/weixin_44391223/article/details/125571723
相關推薦
- 2022-11-06 Swift使用SnapKit模仿Kingfisher第三方擴展優化_Swift
- 2023-07-22 IntelliJ Compilation Error zip END header not foun
- 2022-06-20 WPF使用VisualTreeHelper進行命中測試_實用技巧
- 2022-08-30 大表delete刪數據導致數據庫異常解決_oracle
- 2022-12-05 GPU狀態監測?nvidia-smi?命令的用法詳解_python
- 2022-09-13 Golang優雅保持main函數不退出的辦法_Golang
- 2022-08-15 centos7 redis5安裝
- 2022-06-13 CentOS7.6系統下Docker安裝部署教程_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支