C理解(五):编译,链接库,宏,关键字,变量

这篇具有很好参考价值的文章主要介绍了C理解(五):编译,链接库,宏,关键字,变量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

编译

        编译过程
                文件.c->(预处理)->文件.i->(编译)->文件.S->(汇编)->文件.o->(链接)->elf程序

        预处理
                内容:加载头文件(#include),清除注释(//,./*),替换条件编译(#if #elif #endif    #ifdef),替换宏定义(#define)
                结果:生成.i文件(gcc -E xx.c -o xx.i)
                作用:用于debug调试
                注意:typedef定义由编译器处理

链接库

        静态链接库
                gcc x.c -o x.o -c
                只编译不连接,生成.o文件
                ar打包成 .a文件
                ar crs lib${func1}.a  ${func1}.o
                c创建库(不管是否存在)
                r库中插入模块
                s创建文件索引,创建较大库时候能加快时间
                编译:gcc x.c -o x -lx -L.
                nm查看.a文件中有哪些符号
                注意:gcc默认是动态库链接,-static强制静态链接指定链接(-lxxx),指定动态库地址(-L)

        动态链接库
                gcc x.c -o x.o -c -fPIC
                gcc -o libx.so aston.o -shared 
                -fPIC位置无关码
                -shared共享库方式链接
                指定环境变量LD_LIBRARY_PATH(动态链接库运行时需要被加载)
                编译:gcc test.c -o test -laston -L.

关键字

        static修饰局部变量,形成静态局部变量,静态局部变量分配在数据段/bss段
        register修饰变量会分配在寄存器,用于提升程序运行效率
        extern声明外部全局变量(变量初始化在其他文件)
        volatile变量不被被编译器改变
        void:p = NULL;  <=> p = (void *)0;即0地址处

        '\0','0',0,NULL
                '\0'是转义字符,ASCII编码值是0
                '0'是字符,ASCII编码值是48
                0是数字
                NULL是(void *)0

变量

        局部变量分配在栈上,作用域为代码块作用域,生命周期是临时的,连接属性为无连接,定义时未初始化则值随机,变量地址运行时在栈上随机分配地址
        静态局部变量,分配在数据段/bss段(初始化非0在数据段,初始化0或未初始化在bss段),作用域为代码块作用域,生命周期为永久,链接属性为无连接,静态局部变量<==>全局变量
        static使全局变量和函数链接属性由外部转为内部是为解决重名问题,宏和inline函数的链接属性为无连接

        宏定义
                最值:#define MAX(a,b) (((a)>(b))?(a):(b))
                一年有多少秒:#define SEC_PER_YEAR  (3652460*60UL)
                注意:类型默认int,超int类型范围(UL == unsigned int)

        带参宏,带参函数,inline
                宏定义在预处理期间处理,函数编译处理
                宏定义在调用处展开,函数在调用处跳转执行,执行完跳回
                宏定义原地展开,没有调用开销,函数是跳转执行再返回,有较大调用开销
                带参宏定义不检查参数类型,返回值不附带类型,函数有明确参数类型和返回值类型,调用函数编译会做参数类型检查
                函数体小适合用带参宏,函数体大用函数调用
                inline修饰的函数为内联函数,内联函数编译器做参数静态类型检查也不用调用开销而是原地展开

        debug宏
                #define DEBUG
                #ifdef DEBUG
                #define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", FILE, FUNCTION, LINE); fprintf(stderr, VA_ARGS)
                #else
                #define DBG(...)
                #endif


                __FILE__是预定义宏,在编译的c文件名
                __FUNCTION__是在编译的函数
                __LINE__是在编译的行号
                __VA_ARGS__表示一个或多个参数,类似可变参数中的省略号
                ...表示参数个数和类型是可变的,…为参数占位符


        内核DEBUG宏
                #ifdef DEBUG_S3C_MEM
                #define DEBUG(fmt, args...)   printk(fmt, ##args)
                #else
                #define DEBUG(fmt, args...)   do {} while (0)
                #endif

demo:

        debug宏

#include <stdio.h>

#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__)
#else
#define DBG(...)
#endif

int main()
{
        DBG("test bug\n");
        return 27;
}

结果示例:

C理解(五):编译,链接库,宏,关键字,变量,c语言文章来源地址https://www.toymoban.com/news/detail-728301.html

到了这里,关于C理解(五):编译,链接库,宏,关键字,变量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言深度剖析——第四节(关键字4)】《C语言深度解剖》+蛋哥分析+个人理解

    追求本质,不断进步 本文由@睡觉待开机原创,转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 前言: 本节博客继续前篇内容进行续写,我们着重探求有符号与无符号数的问题,探求 整形在内存中的存储 这一课

    2024年01月20日
    浏览(34)
  • 【C语言趣味教程】(4) 变量:代码注释 | 变量的声明 | 初始化与赋值 | 变量的命名 | 关键字 | 标识符 | 变量名的命名规范

      🔗 《C语言趣味教程》👈 猛戳订阅!!! 0x00 引入:注释的作用 \\\"程序员最讨厌两种人:一种是不写注释的人,一种是让我写注释的人。\\\" 相信大家对注释早已有所耳闻,对于注释,C 语言有两种注释风格,我们下面会逐个讲解。   但在这之前,我们先来了解了解注释的作

    2024年02月15日
    浏览(34)
  • 初始Go语言2【标识符与关键字,操作符与表达式,变量、常量、字面量,变量作用域,注释与godoc】

      go变量、常量、自定义类型、包、函数的命名方式必须遵循以下规则: 首字符可以是任意Unicode字符或下划线。 首字符之外的部分可以是Unicode字符、下划线或数字。 名字的长度无限制。 理论上名字里可以有汉字,甚至可以全是汉字,但实际中不要这么做。 Go语言

    2023年04月09日
    浏览(35)
  • 搜索引擎优化指南:SEO关键字、长尾关键字、短尾关键字以及反向链接

    SEO 代表“搜索引擎优化”。它是一种数字营销策略,旨在提高网站或网页在搜索引擎未付费结果中的在线可见性。通常,网站在搜索结果页面中排名越高,或在搜索结果列表中显示的频率越高,它将从搜索引擎用户那里获得的访问者就越多。 SEO 策略可以针对各种类型的搜索

    2024年02月04日
    浏览(65)
  • 【C语言】scanf和strcpy这类关键字和函数为什么不安全,使用VS编译会报错

    首先先说解决方法: 在程序最顶端加入这个代码段 这主要是微软的 C 运行时库实现将这些函数标记为不安全,主要原因是这些函数缺乏对输入长度的边界检查,容易导致缓冲区溢出漏洞。 会产生这样的报错: 即: C4996    \\\'strcpy\\\': This function or variable may be unsafe. Consider usin

    2024年02月14日
    浏览(48)
  • 动态链接库的__declspec(dllexport)关键字的概念

    在 Windows 操作系统下,创建一个动态链接库(DLL)项目时,您需要通过 __declspec(dllexport) 来显式地标记希望在 DLL 中 公开 的函数、类、变量等符号。这是因为在默认情况下,编译器会将函数和符号视为 私有 ,即它们不会在 DLL 导出表中注册,从而无法从外部访问(通常

    2024年02月11日
    浏览(23)
  • kotlin sealed关键字理解

    Kotlin中的\\\"sealed\\\"用于声明一个\\\"密封类\\\"(sealed class)。密封类是一种特殊的抽象类,用于限制可以继承它的子类。 密封类的主要特点是,它的子类必须定义在与密封类相同的文件中,这样做可以保证只有有限的类可以继承密封类。这种限制能够提供更好的代码可读性和

    2024年02月12日
    浏览(29)
  • 正确理解c# default关键字

    最近QA测试一个我开发的一个Web API时,我意识到之前对C#的 default 的理解一直是 想当然 的。具体情况是这样,这个API在某些条件下要返回模型的默认值,写法类似于下面这样 实际上,这个API会返回 204 No Content ,而不是想象中的一个空的WeatherForecast。API返回204,说明 default 得

    2024年01月16日
    浏览(34)
  • asyncio中await关键字的理解

    在  asyncio  中, await  用于暂停当前异步函数的执行,直到其后的协程(coroutine)完成执行并返回结果。一旦协程完成, await  表达式会返回该协程的结果,并且异步函数会从这个点继续执行。 多个  await  表达式会按照它们在代码中的顺序依次执行。这意味着,如果

    2024年02月21日
    浏览(25)
  • 【正点原子STM32】C语言重点知识(配置MDK支持C99、位操作清零置一、带参数的宏定义、头文件的条件编译和代码条件编译、关键字、结构体指针、代码规范)

    一、stdint.h简介 配置MDK支持C99 二、位操作 如何给寄存器某个位赋值(清零置一) 三、宏定义 带参数的宏定义 四、条件编译 头文件的条件编译和代码条件编译 五、extern声明 六、类型别名(typedef) 类型别名应用 七、结构体 应用举例(定义使用) 应用举例(ST源码,使用类型

    2024年02月19日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包