C语言基础知识点解析(extern,static,typedef,const)

关于C语言基础知识点解析的完整攻略,我将分为四个部分来详细讲解extern、static、typedef、const的定义、用法和示例。

1. extern详解

extern是外部变量或函数的声明关键字。若在一个文件中定义了一个全局变量或函数,而在另一个文件中需要使用该变量或函数,则必须在使用之前用extern进行声明,表示该变量或函数是外部可见的。

extern声明全局变量:

/* file1.c */
int num = 10;

/* file2.c */
extern int num;
int add(int a) {
  return a + num;
}

/* main.c */
#include <stdio.h>
extern int num;
int add(int);
int main() {
  printf(“Add: %d”, add(5)); // should print 15
  return 0;
}

在上面的代码中,file1.c中定义了num,file2.c中通过extern int num声明了num,确保现在可以在file2.c中使用num。最后,main.c通过包含file2.h头文件并链接外部编译单元,可以正确地链接num。

extern声明函数:

/* file1.c */
int num = 5;

/* file2.c */
extern int num;
void hello() {
  printf("Hello, The Number is %d\n", num);
  return 0;
}

/* main.c */
#include <stdio.h>
void hello();
int main() {
  hello();
  return 0;
}

在上面的代码中,file1.c中还是定义了num,在file2.c的函数中使用了num,最后main.c中通过包含file2.h头文件并链接外部编译单元,可以正确地调用hello()。

2. static详解

static关键字在C语言中可以用于不同的场景,以表示不同的含义。在全局变量、局部变量、函数声明、函数定义、结构体中,static都有不同的含义。

static声明全局变量:

/* file1.c */
static int num = 5;

/* file2.c */
extern int num;
void hello() {
  printf("Hello, The Number is %d\n", num);
}

/* main.c */
#include <stdio.h>
void hello();
int main() {
  hello();
  num++;
  hello(); // should print The Number is 5 and 6
  return 0;
}

在上面的代码中,static在全局变量中表示该变量只能在当前编译单元内使用,即该变量的生命周期只存在于当前文件中。在file1.c中定义了一个全局的静态变量num,file2.c中可以通过extern引入num。main.c中调用了hello()两次,分别输出5和6的值,因为static变量num的生命周期只存在于当前文件中,所以累加之后输出的结果不会有变化。

static声明局部变量:

/* file1.c */
#include <stdio.h>
void foo() {
  int test = 5;
  static int static_test = 5; 
  test++;
  static_test++;
  printf(“test: %d, static_test: %d\n”, test, static_test);
}

/* file2.c */
#include <stdio.h>
void foo();

int main() {
  foo();
  foo();
  foo();
  return 0;
}

在上面的代码中,在函数内部使用static声明的变量只具有一次初始化,然后一直存在于函数的生命周期中,不会因为函数执行完毕而被销毁。上述代码中,test每次调用foo函数都会重置为5,而static_test每次调用foo函数都会累加,一直存在于函数的生命周期中,因此输出结果为“test: 6, static_test: 6”、“test: 6, static_test: 7”、“test: 6, static_test: 8”。

static声明函数:

/* file1.c */
static void foo() {
  printf("Hello World\n");
}

/* file2.c */
#include <stdio.h>
static void foo() {
  printf("Hello Everyone\n");
}

int main() {
  foo();
  return 0;
}

在函数声明和函数定义中使用static关键字,表示该函数只能在当前编译单元内部使用,其他文件无法引用该函数。上述代码中,file1.c中定义了一个静态函数foo,file2.c同样定义了一个静态函数foo,但是在main函数中只会输出“Hello World”,因为静态函数foo只能在file1.c中被访问。

3. typedef详解

在C语言中,typedef允许我们创建新的数据类型别名。通过typedef关键字,可以对已经存在的数据类型进行取别名操作。

typedef int new_int;

上述代码的意思是将int类型重新取别名为new_int。在代码中,我们可以定义变量或参数时使用这个别名来代替int类型。

new_int num = 10; 

在这种情况下,num的数据类型就是新定义的new_int。

typedef与结构体:

不仅如此,typedef与结构体配合使用还可以定义新的数据类型。

typedef struct {
  int x;
  int y;
} Point;

上述代码将一个结构体定义为名为Point的新数据类型。以后可以使用Point类型来定义结构体类型的变量:

Point p1 = {1, 2};
p1.x = 5;

typedef与指针:

typedef也可与指针类型一起使用。指针的定义从char,int等等改为了自定义的别名,如CharPtr、IntPtr等。

typedef char* CharPtr;
typedef int* IntPtr;

CharPtr str = "hello";
IntPtr num = 5;

typedef与函数:

typedef也可以用于函数指针。

typedef int (*FuncPtr)(int);

int add(int a) {
  return a + 1;
}

int minus(int a) {
  return a - 1;
}

int main() {
  FuncPtr func = add;
  printf("%d\n", func(5)); // should print 6

  func = minus;
  printf("%d\n", func(5)); // should print 4
  return 0;
}

上述代码定义了一个FuncPtr类型的函数指针,该指针指向一个int(int)函数。

4. const详解

const是一个关键字,表示定义的变量是只读的,在程序运行的过程中不能修改。

const定义常量:

const int num = 7;

上述代码中,将整数7定义为只读变量num。在程序运行过程中,不能对该变量进行修改。

指针和const:

在指针前加const会使指针所指向的变量成为只读的。

int a = 5;
const int* b = &a;

*b = 6; // ERROR

上述代码中,const int前加了*,因此其表示的是一个指向常量的指针。在程序运行过程中,不能修改指针b所指向的变量a。

const和函数:

在函数定义中,const可以表示该参数是只读的。

void print(const char* str) {
  printf("%s", str);
}

上述代码表示参数str是只读的,在函数内部不能对该参数修改。

注意事项:

需要注意的是,在C语言中const并不是对变量的值进行限制,而仅仅是对第一次定义时所赋的值进行限制,之后对该变量的操作不被限制。

const int num = 10;
int* ptr = (int*)&num;
*ptr = 11;
printf("num = %d\n", num); // should print 10 instead of 11

上述代码中,虽然num通过const定义成为只读变量,但是我们可以通过指针的类型强转与指针操作,来对其进行修改。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言基础知识点解析(extern,static,typedef,const) - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 动态样式类封装JS代码

    动态样式类封装JS代码是一种实现动态样式的技术,它可以通过JavaScript来操作DOM元素的CSS样式属性,从而实现页面中元素动态变化的效果。 下面是实现动态样式类封装JS代码的完整攻略: 创建动态样式类 首先要创建一个动态样式类,该类需要包含一些CSS样式属性,可以使用JavaScript的createElement方法动态创建该类: var styl…

    other 2023年6月25日
    00
  • 如何使用正则表达式验证用户名?

    如何使用正则表达式验证用户名攻略 在Web开发中,我们经常需要验证用户输入的用户名是否符合规范。正则表达式是一种强大的工具,可以用于验证用户名是否合特定的格式。本攻略将介绍如何使用正则表式验证用户名,并提供两个示例。 正则表达式 则表达式是一种用于匹配字符串的模式。它由一些特殊字符和普通字符组成,可以用于验证字符串是否符特定的格式。以下是一些常用的正则表达式…

    other 2023年5月9日
    00
  • gta5最全mod整合包2022

    感谢您对我的提问,下面是对 gta5 最全 Mod 整合包 2022 的完整攻略: 1. 确定你的游戏版本 在开始之前,请确保你的游戏版本和 Mod 版本兼容,如果不兼容,Mod 无法正常运行。首先,你需要在游戏设置里找到 GTA5 版本号码。 2. 下载 Mod 整合包 接下来,你需要下载最全 Mod 整合包 2022,这里选择 gta5mods.com …

    其他 2023年4月16日
    00
  • ensp防火墙简单配置

    以下是关于“ensp防火墙简单配置”的完整攻略,过程中包含两个示例。 背景 ENSP是华为公司推出的一款网络安全产品,其中包括防火墙功能。在使用ENSP防火墙时,我们需要进行一些简单的配置,以确保其能够正常工作。本攻略将介绍如何进行ENSP防火墙的简单配置。 基本原理 ENSP防火墙是一种网络安全设备,用于保护网络免受恶意攻击。在使用ENSP防火墙时,我们需…

    other 2023年5月9日
    00
  • 讨鬼传极 部分武器槽相关技能数据测试

    当然,下面是关于《讨鬼传极》中部分武器槽相关技能数据测试的完整攻略,包含两个示例说明: 步骤1:选择武器和技能 首先,选择您要测试的武器和相关技能。确保您已经了解每个技能的效果和作用。 示例说明一:测试火属性武器槽技能- 武器:火属性长剑- 技能:烈焰斩、火焰爆发、火焰附加 示例说明二:测试雷属性武器槽技能- 武器:雷属性弓箭- 技能:雷电射击、雷暴之力、雷…

    other 2023年10月17日
    00
  • linux shell awk获得外部变量(变量传值)简介

    当我们编写Linux shell脚本时,有时需要从外部获取变量并在脚本中使用。而awk是Linux环境下非常常用的文本处理工具之一,也可以在其中使用外部变量。本攻略将详细讲解如何在awk中获得外部变量。 准备工作 在学习如何在awk中获取外部变量之前,我们需要先了解一下-v选项。-v选项可以向awk脚本中传递一个变量,并将该变量赋值为一个名为awk的变量。 …

    other 2023年6月27日
    00
  • 如何查看linux硬件配置信息

    如何查看Linux硬件配置信息 在Linux系统中,您可以使用一些命令来查看硬件配置信息。以下是使用Linux命令查看硬件配置信息的完整攻略。 1. 使用lshw命令 lshw是一个用于显示硬件信息的命令工具。您可以使用以下命令安装lsh: sudo apt-get install lshw 安装完成后,您可以使用以下命令查看硬件配置信息: sudo lsh…

    other 2023年5月6日
    00
合作推广
合作推广
分享本页
返回顶部