C语言中的变量和函数的定义与声明

在C语言中,编译源文件是从第一行到最后一行,逐行编译的,而且在多个文件同时编译时,是逐个文件编译的,即无全局预扫描,所以严格要求调用前需要出现定义或声明。因此变量和函数的调用是在定义/声明之后的,本文将主要介绍变量和函数如何在C中定义和声明。

一、概念详解

1、定义变量(definition):分配内存,只能出现一次;写在任意一个.c源文件全局区

2、声明外部全局变量(declaration):告诉编译器这个变量名存在、类型存在、内存在别文件,不分配内存;使用关键字extern,可写在其他.c或.h文件。

3、变量的定义和声明

外部变量(非本文件中定义的变量):extern 变量的类型 变量名

本部变量: 变量类型 变量名

4、函数的定义和声明

外部函数(非本文件中定义的函数):extern 外部函数头

本部函数:函数头

函数的声明:形参的名字可以不要,也可以要,但是类型一定要

c 复制代码
extern def_v(int,int);
extern def_v(int a,int b);

二、工程示例

1、定义变量和函数的源文件

c 复制代码
#include<stdio.h>
#include<windows.h>


//全局变量定义,分配内存和初始化
int global_num=666;
char global_str[]="跨文件变量";


void print_def(void){
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    printf("测试全局变量访问和函数调用%d %s\n",global_num,global_str);
}

2、调用外部变量和函数的源文件

c 复制代码
extern int global_num;
extern char global_str[];
extern void print_def(void);
int main(int argc, char const *argv[])
{
    /* code */
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    printf("主函数在调用外部全局变量%d %s\n",global_num,global_str);
    global_num = 888;
    print_def();
    return 0;
}

3、编译与运行结果

由于存在多个源文件,所以编译多个.c文件均需要编译(把所有.c源文件一次性交给gcc,gcc自动处理跨文件extern关联)

补充:

C语言编译分为编译阶段和链接阶段

编译阶段:单个.c生成目标文件.o,只做语法检查,extern只做标记,不寻找变量实体;

链接阶段:把所有.o文件合并,解析extern对应的真是变量的内存地址,找不到则报"undefined reference"链接错误

4、推荐global.h头文件统一存放extern声明

在实际项目中,每个c文件重复写extern,全局变量管理比较混乱,建议统一放到头文件。

之后任意.c文件只需要#include global.h,就会自动导入所有外部变量和函数声明,不用重复写extern。

三、常见错误与原因

当所有.c文件里都没有写变量定义,但是写了extern int 变量名,链接器就找不到变量实体,会报错

相关推荐
孫治AllenSun2 小时前
【DataX】生产环境搭建DataX集群案例
java·开发语言·jvm
c238563 小时前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
moonsims4 小时前
星闪在跨域无人化系统作用
开发语言·php
aaaameliaaa4 小时前
指针之总结
c语言·笔记·算法
码农coding5 小时前
android 12 中的VSYNC的请求
android
阿pin5 小时前
Android随笔-Activity
android·activity
Iruoyaoxh5 小时前
栈和队列~
java·开发语言
agathakuan5 小时前
Wireshark 解密並導出TLS 1.2 / TLS 1.3 明文的方法(可控制 Client 端)
c语言·wireshark·ssl·openwrt
caimouse5 小时前
protoc-gen-c 支持 proto3 `optional` 关键字修改记录
c语言·学习