深度解析Linux-C——函数进阶(static、const、extern、auto、register、volatile关键字,回调函数、 inline内联函数,gcc编译多个文件)

目录

static静态变量

const常量

C语言其他关键字

extern关键字 

 inline 内联函数

递归函数

回调函数

 gcc定义编译多个文件


static静态变量

使用 static 修饰的变量就是静态变量, 静态局部变量 ,静态全局变量

1.静态局部变量  只能被初始化1次  ,存储在数据段,不会释放。 
2.静态全局变量,只能在当前文件使用,无法跨文件使用,防止全局变量名冲突。 

static静态函数
static 修饰函数只能在当前文件使用,防止与其他文件的函数名冲突

比如:

test.c文件

// 设置为静态函数,只能在当前文件调用,不会与 test1.c 里面的show名字冲突  
static void show(){
    printf("static 2024-7-23 14:30:59\n");
}

void test(){
    printf("test 今日的时间:");
    show();
}

test1.c

void show(){
    printf("2024-7-23 14:30\n");
}

void test1(){
    printf("test1 今日的时间:");
    show();
}

 test.c和test1.c文件中虽然都有show()函数,但是test.c中的是静态函数,所以最后在main函数中调用的时候,只会调用test1.c中的show函数

const常量

常量不能被修改,系统不会检查常量的变化

但是如果去修改常量所在地址的值,常量还是会被修改

如:

#include <stdio.h>

int main()
{
    const int a = 100;
    int *p = &a;
    *p = 200;
    printf("%d", a);
}

 输出a等于200

所以引用常量指针的概念

int value = 10;    
const int val = 100; 

const int *p = &value;        // 常量指针,无法修改地址上的内容
int const *p1 = &value;       // 常量指针,无法修改地址上的内容
int *const p2 = &value;       // 指针常量, 指针指向的地址无法修改
const int *const p3 = &value; // 常量指针常量,无法修改地址上的内容,无法修改指针指向的地址

 //----修改地址上的内容----------

*p = 123;  // 修改地址上的内容 ,错
*p1 = 123; // 修改地址上的内容,错
*p2 = 123; // 可以的
*p3 = 123; // 修改地址上的内容 ,错


 //----修改指针的,指向---------

p = &val;
p1 = &val;
p2 = &val; // 不可以,指针常量,无法修改指向
p3 = &val; // 不可以

C语言其他关键字

声明value是一个自动变量,但是现在的编译自动会处理,不需要声明,在cpp中已经被废弃了,并修改了功能

auto int value = 100; 

寄存器变量, 把tmp 存储到CPU寄存器中,而不是内存中。寄存器的访问效率比内存高!
所以一些经常访问的变量,可以设置为寄存器变量,提高访问效率。
现在的编译器,都会自动把访问频繁的变量放入寄存器中

register int tmp = 100;

不可忽略变量,易变变量。 如果在CPU 中做一些空循环,
编译器有可能会忽略,如果不想编译器忽略,则需要把变量声明,为volatil
在单片机中应用比较多

volatile int val = 100;

//例如
for (int val = 0; val < 100000; val++);     // 该循环没有任何意义,某些编译器会直接忽略掉。

extern关键字 

外部变量,多文件编写时能实现跨文件的访问

例如

xxxx.c

//声明全局变量a,b不在当前文件中
extern int a;
extern int b;

void swap()
{
	temp = a;
	a = b;
	b = temp;
	printf("a = %d, b = %d", a, b);
}

main.c 

#include <stdio.h>

int a = 10, b = 20;  //定义全局变量

void swap(); //声明
int main()
{
	void swap(); //调用
}

 inline 内联函数

        如果用户不想一个函数发生进栈与出栈的操作,用户可以把一个函数设置为 inline 内联函数,这样代码就会直接内嵌到程序中,不发生任何的栈操作,提高执行效率。  

        函数封装使得我们的程序模块化,开发和维护都变得更简单,但是函数调用的一个代价是需要消耗一定的时间进行切换,这段时间用来保存现场和恢复现场,比如在执行函数A的时候,中途调用函数B,那么在调用前一刻必须将函数A的执行状态记录下来,包括些寄存器的值,当下的执行地址等,以便于将来执行完函数B返回之后,可以继续原来的状态执行下去。

#include <stdio.h>
//一定要先声明max内联函数,否则找不到该函数,已经内嵌到代码中。
int max(int x, int y);

// 声明并定义内联函数
inline int max(int x, int y){
    int z = 0;
    z = x > y ? x : y;
    return z;
}

int main()
{
    int x = 10, y = 20;
    int tmp = max(x, y);
    printf("tmp=%d\n", tmp);
}

递归函数

在函数中调用函数.

回调函数

用函数指针,指向一个函数,并调用该函数,这种设计方法是实现C 语言的多态 

多态:一个函数接口拥有不同的功能状态。  一个接口实现多种功能,提高代码的复用性

多态是面向对象的基石

比如封装一个比较大小的函数

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
// bool (*cmp)(void *, void *) 指向一个比较两个数据的方法

bool big(bool (*cmp)(void *, void *), void *a, void *b)  //调用某个函数的地址
{
    if (cmp(a, b))
    {
        return true;
    }
    else
    {
        return false;
    }
}
比较整形方法
bool cmp_int(void *a, void *b)
{
    int *p = a;
    int *q = b;

    return *p > *q;
}

// 比较浮点
bool cmp_float(void *a, void *b)
{
    float *p = a;
    float *q = b;

    return *p > *q;
}

// 比较字符串
bool cmp_string(void *a, void *b)
{
    char *p = a;
    char *q = b;

    if (strcmp(p, q) == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    int a = 200, b = 100;
    printf("%d\n", big(cmp_int, &a, &b)); // 修改比较方法 cmp_int

    float f = 3.14;
    float f1 = 2.33;
    printf("%d\n", big(cmp_float, &f, &f1)); // 修改比较方法  cmp_float

    char *s = "1234";
    char *s1 = "12314";
    printf("%d\n", big(cmp_string, s, s1)); // 修改比较方法  cmp_float
}

 

 gcc定义编译多个文件

比如以下三个文件

 xxxx.h

#ifndef  STR
#define STR
{
    //函数声明;
}
#endif

 xxxx.c

#include "xxxx.h"  //注意,一定要是双引号引用头文件,<  >会报错
{
	//函数的定义;
}

 main.c

#include <stdio.h>
#include "xxxx.h"

int main()
{
	函数的调用
}

 编译方法:         

gcc main.c xxxx.c -o main && ./main

 字符串函数,数据转换函数.......更多函数,参见Linux-c函数库

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值