如何提高C编程能力

简介: 目前C语言被应用得最多的估计就是嵌入式了,在学校学习完C语言,考完等级考试之后,可能就会觉得自己的C语言掌握的还可以了。但这其实只能算入门,像结构体,指针等内容还有很多东西需要去深究,还有GNU的一些补充语法。接下来,我们来探讨一下如何提升!


前言

   目前C语言被应用得最多的估计就是嵌入式了,在学校学习完C语言,考完等级考试之后,可能就会觉得自己的C语言掌握的还可以了。但这其实只能算入门,像结构体,指针等内容还有很多东西需要去深究,还有GNU的一些补充语法。接下来,我们来探讨一下如何提升!

打怪升级

1. C语言三剑客

   C语言经典三剑客《C和指针》《C陷阱与缺陷》《C专家编程》,这三本书相信很多人都听过。对于想提升C编程能力,这三本是绝对要去阅读一下的。单纯阅读肯定很枯燥,所以阅读过程中还是要去动动手的。这三本书的章节其实也没什么必然的关联性,所以建议大家可以挑着看,最近想看研究一下指针,就看"指针"的章节,  想研究动态内存分配, 就看"动态内存分配"章节。毕竟这不是入门书籍。

2. GNU C语法

   首先我们先来了解一些概念,ANSI C 、POSIX C、GNU C到底是啥?之间到底有啥关系?

    • ANSI C :由美国国家标准局为C语言制定了一套完整的国际标准语法,称为ANSI C,作为C语言最初的标准。
    • POSIX C : POSIX中文翻译:可移植操作系统接口,POSIX标准的诞生是为了统一个操作系统的接口,方便开发者开发程序,写出可移植的代码程序。
    • GNU C:GNU的C函数库,其实就是glibc,它是Linux上最重要的函数库,它定义了 ANSI C 标准指定的所有的库函数,以及由POSIX或其他UNIX操作系统变种指定的附加特色,还包括有与GNU系统相关的扩展。

       OK, 有了上面的概念之后。你可能会明白为什么有时候会看到一些奇怪的语法,然后去查课本又找不到。目前大学里的课本是按ANSI C来编写的,都是标准的C语言语法。所以也不用骂课本垃圾,语法编写不完整!

       回到GNU C上面,GUN C提供了一些新的语法功能,对于做Linux开发的,肯定是必须要接触的。比如:GNU C支持零长度数组。

    typedef struct test1{
        int len;
        char a[0];    // 零长度数组
     }TEST1;

    image.gif

    这个时候数组是不占用内存的,如果声明指针是会占用内存的。这玩意有什么作用呢?简单看一下下面的代码:

    #include<stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct test1{
      int a;
      char b[0]; //零长度数组
    }TEST1;
    int main()
    {
      char str[] = "helloworld";
      //malloc分配空间
      TEST1* test1 = (TEST1*)malloc(sizeof(TEST1) + 20);
      printf("%p\n", &(test1->a));
      printf("%p\n", (test1->b));
      //字符串复制
      memcpy(test1->b, str, sizeof(str));
      printf("%s\n", test1->b);
    }

    image.gif

    这个时候我们就可以通过结构体(TEST1)成员b去访问后面的地址了。它更多是被用在长度不确定的数据上。大家还可以去思考对比一下和指针的差异!

    更多GNU C相关内容可以到http://www.gnu.org/software/libc/manual 学习。

    3. 阅读开源代码

       个人认为,阅读一下好的开源代码或者原厂提供的一些SDK,对于个人编码能力会有很大提升。学习他们一些好的编码规范和整体架构设计理念,最最经典的当然就是Linux系统了。其实阅读源码并不一定要完全理解代码功能之类的 ,我们更多是去学习为什么这么写, 这么写用什么好处。当然了,也并不是所有都是好的,我们也是取其精华去其糟粕嘛!

       来看个小例子

    #define MAX( a, b) ( (a) > (b)?(a) : (b) )
    int max( int a, int b)
    {
      return ((a > b)? a : b);
    }

    image.gif

    上面是要对比两个数的大小,一个是用宏实现,一个使用函数实现。你觉得哪个比较好

       首先,宏会比较简洁;然后宏可以传递各种类型的参数,而函数只能传递int类型的;最后函数调用会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。

    但是宏也有缺点,宏在预编译时会拷贝到所有调用的位置,这样就会使编译出来的文件变大。

       所以这需要看实际情况来选择了,这个东西我也是在Linux源码上发现的,Linux最近更新的版本很经常将一些函数替换成宏的形式。所以多阅读,多思考,会提升很快的!

    image.gif

    4. 多踩坑,多思考

       这东西说起来很虚,实践出真知!只有在做项目的时候,你才会知道,原来某些东西组合起来一起用会有这么多坑。还有就是多思考,多总结,这绝对会事半功倍!不要觉得,反正是“面向浏览器编程”,记那么多干嘛。

    image.gif

    总结

       说得再多也没用,最主要还是要行动起来。打怪升级的路上很辛苦,努力!努力!努力! 分享就到这,欢迎探讨,指教!

     


    相关文章
    |
    3月前
    |
    人工智能 安全 算法
    基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。
    本文深入探讨了基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。C语言因其高效、可移植、灵活及成熟度高等特点,在嵌入式系统开发中占据重要地位。文章还介绍了从系统需求分析到部署维护的完整开发流程,以及中断处理、内存管理等关键技术,并展望了嵌入式系统在物联网和人工智能领域的未来发展。
    149 1
    |
    6月前
    |
    Rust 安全 数据挖掘
    【颠覆常规】Rust科学计算革命:掌握数值分析与数据处理的全新利器,让你的工作事半功倍!
    【8月更文挑战第31天】Rust语言凭借其出色的内存安全和高性能特性,在科学计算领域逐渐崭露头角。本文通过具体代码示例展示了Rust在数值计算与数据分析中的应用,包括矩阵乘法、统计分析及线性方程组求解。通过安装Rust并引入`ndarray`、`nalgebra`和`statrs`等库,读者可以轻松实现各类科学计算任务。Rust在科学计算领域的潜力巨大,未来可期。
    326 1
    |
    6月前
    |
    敏捷开发 设计模式 开发者
    【揭秘终极利器】AgileEAS.NET:服务定位器模式的魔法,如何让企业级软件开发瞬间提速?揭秘背后的技术奥秘与实战指南!
    【8月更文挑战第16天】AgileEAS.NET是基于DotNet的企业级敏捷开发平台,其服务定位器模式助力构建高度解耦系统。通过全局服务目录动态查找服务,避免硬编码依赖。在AgileEAS.NET中,服务定位器以静态类形式封装服务注册与检索功能。示例展示了如何注册与获取服务实例,如在`UserController`中通过服务定位器使用`IUserService`。此模式整合到框架生命周期管理,便于各处获取服务实例,提升开发效率。然而,应适度使用并考虑依赖注入容器以增强代码可维护性和可测试性。
    95 4
    |
    6月前
    |
    Rust 安全 图形学
    Rust图形革新:2D与3D编程的全新体验,它能否颠覆传统?
    【8月更文挑战第31天】随着Rust语言的日益成熟,其在图形编程领域的应用逐渐增多。本文将探讨Rust在图形编程中的表现,从2D扩展至3D。通过使用`pixman`库处理2D图形,以及借助`naga`库实现3D渲染,展示了Rust在图形编程中的潜力。尽管与C++相比,Rust的生态仍在发展中,但其安全性与性能使其成为图形编程的重要工具之一,值得开发者关注和学习。
    216 0
    |
    6月前
    |
    Java 数据库连接 数据库
    AI 时代风起云涌,Hibernate 实体映射引领数据库高效之路,最佳实践与陷阱全解析!
    【8月更文挑战第31天】Hibernate 是一款强大的 Java 持久化框架,可将 Java 对象映射到关系数据库表中。本文通过代码示例详细介绍了 Hibernate 实体映射的最佳实践,包括合理使用关联映射(如 `@OneToMany` 和 `@ManyToOne`)以及正确处理继承关系(如单表继承)。此外,还探讨了常见陷阱,例如循环依赖可能导致的无限递归问题,并提供了使用 `@JsonIgnore` 等注解来避免此类问题的方法。通过遵循这些最佳实践,可以显著提升开发效率和数据库操作性能。
    108 0
    |
    7月前
    |
    数据采集 传感器 程序员
    LabVIEW程序员应该怎么提高自己的工作能力?
    LabVIEW程序员应该怎么提高自己的工作能力?
    71 1
    |
    7月前
    |
    网络协议 开发者 Python
    颠覆传统!Python Socket编程新思维,基础与进阶并重,打造卓越网络能力!
    【7月更文挑战第25天】在数字时代,网络通信至关重要,Python的Socket编程简化了这一复杂领域,使初学者也能轻松上手。通过Python的`socket`模块,我们能快速搭建服务器与客户端,实现数据交换。示例代码展示了如何创建、绑定及监听Socket,以及收发消息。掌握基础后,可利用asyncio库探索异步编程,提升通信效率,处理多连接。Python的Socket编程,结合传统与现代技术,助力开发者在网络通信领域取得非凡成就。
    94 0
    |
    9月前
    |
    存储 缓存 算法
    作者推荐 | 【底层服务/编程功底系列】「底层技术原理」史上最清晰的采用程序员的视角方式进行深入探索Linux零拷贝技术原理及实现
    作者推荐 | 【底层服务/编程功底系列】「底层技术原理」史上最清晰的采用程序员的视角方式进行深入探索Linux零拷贝技术原理及实现
    72 0
    |
    9月前
    |
    Java API
    【底层服务/编程功底系列】「手把手教学系列」带你打造一个属于自己的规则引擎服务,打破任何业务难题(逻辑模型和API设计)(三)
    【底层服务/编程功底系列】「手把手教学系列」带你打造一个属于自己的规则引擎服务,打破任何业务难题(逻辑模型和API设计)
    130 0
    |
    9月前
    |
    Java 大数据 Android开发
    探索Java编程语言的优势和应用领域
    Java是一种广泛应用于软件开发领域的高级编程语言。它凭借其强大的功能和丰富的生态系统,在众多应用领域中得到了广泛应用。本文将为您介绍Java的优势以及它在各个领域中的应用。
    915 2