Linux和C语言(Day 12)

news2024/9/20 5:40:03

一、学习内容

  1. 存储类型

    1. 定义变量语法格式

      1. 数据类型 变量名; 存储类型 数据类型 变量名; 【定义变量可以省略存储类型,默认是auto】

    2. 定义函数语法格式

      1. 数据类型 函数名(参数){} 存储类型 数据类型 函数名(参数){} 【定义函数可以省略存储类型,默认是extern】

    3. 存储类型的作用是什么啊?

      1. 作用域——能够被使用的范围

      2. 生命周期——从定义分配内存到释放内存的周期,程序执行阶段

      3. 默认值——使用不同的存储类型,定义未赋初值的话,默认值不同【0、随机值】

    4. 存储类型auto

      1. 定义变量未定义存储类型,默认是auto。

        1. auto不能修饰全局变量。

        2. auto修饰局部变量,()形参、{}

        3. 默认值是 随机值。

    5. 存储类型 register

      1. register修饰的是寄存器变量。

      2. register修饰的变量 不能进行 &取地址操作。

      3. 默认值是 随机值

      4. CPU从内存取数据,发送给运算器进行数据处理,把结果有存入内存。CPU自己也有内存——寄存器,对于使用频率特别高的数据可以放在寄存器里面,CPU取数据的效率【寄存器 > cache(高速缓存) > 内存】。但是不能不能把所有变量都放在寄存器中,因为寄存器特别小。

    6. 存储类型static【静态】

      1. 延长生命周期 静态局部变量定义时分配内存,程序结束才释放内存,只赋初值一次。

      2. 限制作用域 静态全局变量和静态函数只能在该文件内使用,不能被外部文件引用。

      3. 定义未赋初值,默认值是0

    7. 存储类型extern【引入外部变量/函数】

      1. 若在1.c文件中定义了一个全局变量,想在2.c文件中使用,使用extern修饰该变量

      2. 若在1.c文件中定义了一个函数,想在2.c文件中使用,使用extern修饰该函数

    8. 存储类型const【常量】

      1. const修饰变量,表示常量化。

        1. 修饰变量,不可以修改值。 const int a = 666; a = 10; //报错

        2. const修饰指针,需要观察 const 与 * 的位置关系,位置不同,作用不同。

          1. cont int *p; 或者 int const *p 【可以修改地址、不可以修改值】

          2. nt * conts p; 【不可以修改地址、可以修改值】

          3. conts int * const p; 【值和地址都不可以修改】

  2. 宏 [不加分号]

    • 宏 是预处理命令,用于语法替换。

    • 语法格式: #define 宏名 字符串

    • 注意:

      • 以#开头的属于预处理命令,不是C语言语句,不加分号

      • 宏名符合命名规范 最好大写 MAX N MAXSIZE

      • 宏只做替换,不做运算

      • 宏没有类型检查,所以替换的全是字符串

    • 自定义宏函数

      • 使用({})

        • 使用({})定义宏函数,如函数只有一条语句,可以省略({})

        • 如有多条语句,返回最后一条语句的结果

        • 语法格式

          • #define 宏名(参数) ({语句1; 语句2; 语句3;})

          • 注意:宏函数的参数不带数据类型,只写参数名占位即可

      • 使用do...while(0)

        • 语法格式

          • #define 宏名(参数) do{语句1;语句2;语句3;}while(0)

    • 宏 与 条件编译

      • ==============判断宏是否为真====
        #if TURE
        执行语句
        #endif
        注释:
        #if 0
        被注释的语句……
        #endif
        #define TURE 1
        #define FALSE 0

      • ========================判断宏已经定义=====
        #ifdef 宏名
        执行语句
        #endif

      • =======================判断宏未定义=======
        #ifndef 宏名
        执行语句
        #endif

      • ======================判断多个宏定义=====
        #defined(宏名1) && defined(宏名2)
        执行语句
        #endif

      • =======================判断多个宏未定义=====
        #ndefined(宏名1) && ndefined(宏名2)
        执行语句
        #endif

      • ======================取消宏====
        #undef
        宏名

  3. typedef 【重定义数据类型】

    • 重定义数据类型

      • typedef int N; //N a; 等价于 int a;

      • typedef int N[3]; //N a; 等价于 int a[3];

      • typedef int *N; //N a; 等价于 int *a;

      • typedef int **N; //N a; 等价于 int **a;

      • typedef int *N[3]; //N a; 等价于 int *a[3];

      • typedef int (*N)[3]; //N a; 等价于 int (*a)[3];

      • typedef int (*N)(); //N a; 等价于 int (*a)();

      • typedef int (*N[3])(); //N a; 等价于 int (*a[3])();

    • 数据结构中

      • struct student{
        int id;
        char name[20];
        float score;
        };
        定义学生变量 struct student a;
        typedef struct student{
        int id;
        char name[20];
        float score;
        }XS;
        定义学生变量 XS a;

  4. 多文件编程

    • 实际的编程中,我们是把所有内容都写在一个.c文件吗

      • 不是的。我们会根据内容/数据的不同放在不同的文件中。

    • 基础学习的过程中: 一般把头文件、宏定义、全局变量、函数声明放在 XXX.h头文件中 把函数实现放在 XXX.c文件中 主函数单独放在 main.c文件中 使用vim -O XXX.h XXX.c main.c 新建三个文件

    • 问题

      • 一个#include只能包含一个头文件,若需要引入多个头文件,写多个#include

      • 一个头文件可以多次引入吗

        • 效果和引入一个一样 但是在预处理阶段,都会展开头文件 我们需要防止头文件多次引入 在XXX.h头文件中 #ifndef __HQYJ__ #define __HQYJ__ #include <stdio.h> #include <string.h> 定义全局 函数声明 …… #endif

      • #include 包含命令中 "" 和 <> 的区别是什么?

        • "" 先在当前路径下找,找不到去库文件中找 <> 直接去库文件中找

  5. 面试题总结

    • typedef和define的区别?

      • 语法不一样 typedef加; 是C语句 define不加; 不是C语句

      • 作用不一样 typedef用于给已有的数据类型重命名 define定义宏

      • define是预处理命令,在预处理直接替换,不做类型检查 typedef在编译时要进行类型检查

    • static的作用

      • 延长生命周期 静态局部变量定义时分配内存,程序结束才释放内存,只赋初值一次。

      • 限制作用域 静态全局变量和静态函数只能在该文件内使用,不能被外部文件引用。

      • 定义未赋初值,默认值是0

    • const的作用

      • 修饰变量,不可以修改值

      • const修饰指针,需要观察 const 与 * 的位置关系,位置不同,作用不同。

        • cont int *p; 或者 int const *p 【可以修改地址、不可以修改值】

        • int * conts p; 【不可以修改地址、可以修改值】

        • conts int * const p; 【值和地址都不可以修改】

  6. 脑图

二、总结

1. 学习内容概述

多文件编程

学习了如何将程序分成多个文件进行编写和组织,主要包括头文件的创建与引用、源文件的分离以及使用`extern`关键字进行跨文件变量共享。

typedef与结构体

学习了使用`typedef`为复杂的类型定义别名,尤其是在结构体中的应用。`typedef`可以简化代码,增加可读性,常用于定义结构体类型的别名。

宏定义

宏定义是C语言中的一种预处理器指令,通过`#define`定义常量和函数型宏,宏在程序编译前被预处理器替换。了解了宏的优势(如提高代码复用性和简化重复逻辑)以及潜在的陷阱(如宏扩展时的优先级问题)。

字符处理函数

学习了如何使用标准库中的字符处理函数(如`strlen`, `strcpy`, `strcat`, `strcmp`等)进行字符串操作。这些函数提供了常用的字符串处理功能,避免手动实现复杂的字符串操作逻辑。

 2. 学习难点

多文件编程的组织

虽然多文件编程可以提升程序的模块化和可维护性,但合理组织多个源文件、确保正确的头文件引用和依赖管理是学习的一个难点。特别是理解`extern`关键字的作用和如何避免重复定义变量。

宏定义的调试

宏并不像函数那样可以进行类型检查,容易导致隐藏的错误。复杂的宏定义在预处理器展开时,可能会因为操作符优先级问题导致意外的行为,调试较为困难。

字符数组与指针的混淆

在字符串操作时,字符数组和字符指针的使用容易混淆。尤其是在处理字符串长度或字符串拷贝时,可能会出现越界或者内存访问错误。

 3. 注意事项

头文件的保护机制

在编写头文件时,应该使用“头文件保护”机制,避免重复包含头文件。可以通过`#ifndef`, `#define`, `#endif`来确保头文件只会被编译器加载一次。

宏的使用

在编写宏定义时,应该谨慎处理宏中的操作符优先级问题,可以使用括号明确表达式的计算顺序。同时,避免使用过于复杂的宏,尽量用`inline`函数替代复杂的宏定义。

字符串处理中的边界问题

在处理字符串时,特别是使用`strcpy`, `strcat`等函数时,需确保目标数组有足够的空间存储结果,避免越界操作导致的缓冲区溢出问题。

多文件编程中的依赖管理

在多文件编程时,应该保持代码结构的清晰,合理拆分代码模块,确保每个文件职责单一,避免源文件之间的相互依赖和耦合。

4. 未来学习的重点

Makefile的学习与使用

在多文件编程中,Makefile是管理编译过程的重要工具。未来可以学习如何编写Makefile,自动化管理多个源文件的编译与链接,提升编程效率。

深入研究宏与内联函数的性能对比

宏虽然在一定程度上可以提高代码效率,但由于缺乏类型检查,容易出现问题。可以深入研究宏与`inline`函数的性能和使用场景,选择合适的优化手段。

字符串操作的安全性

未来可以进一步学习如何使用更安全的字符串操作函数,如`strncpy`, `strncat`等,避免因缓冲区溢出带来的安全隐患。

探索动态内存管理与指针

字符串操作涉及大量的内存管理问题,可以深入学习`malloc`, `free`等动态内存管理函数,掌握如何安全高效地分配和释放内存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PostgreSQL】安装及使用(Navicat/Arcgis),连接(C#)

简介 PostgreSQL 是一个功能强大的开源对象关系数据库系统 下载地址 PostgreSQL: Downloads 由于我电脑上安装的是arcgispro3.1所以需要下载对应的postgresql版本 PostgreSQL 12 对应的 PostGIS 版本主要是 3.5.0 或更高版本。 安装 一般设置为postgresql 安装扩展插件 此…

计算机的错误计算(九十一)

摘要 讨论自然对数 ln(x)的计算精度问题。 例1. 计算 ln(0.999999999999996) . 不妨用Python计算&#xff0c;则有&#xff1a; 若用Java代码计算&#xff1a; import java.lang.Math; public class Ln{public static void main(String[] args) {double x 0.9999999999999…

JMeter脚本开发

环境部署 Ubuntu系统 切换到root用户 sudo su 安装上传下载的命令 apt install lrzsz 切换文件目录 cd / 创建文件目录 mkdir java 切换到Java文件夹下 cd java 输入rz回车 选择jdk Linux文件上传 解压安装包 tar -zxvf jdktab键 新建数据库 运行sql文件 选择sql文件即…

操作系统 ---- 调度算法的评价指标

一、调度算法评价指标 1.1 CPU利用率 资源利用率。为提高系统的资源利用率&#xff0c;应使系统中的处理机和其它所有资源都尽可能地保持忙碌状态&#xff0c;其中最重要的处理机利用率可用以下方法计算&#xff1a; 例题&#xff1a; 1.2 系统吞吐量 由于吞吐量是指在单位…

Playwright与Selenium的对比:谁是更适合你的自动化测试工具?

在自动化测试领域&#xff0c;Selenium 一直是行业的标杆工具。它功能强大、支持多浏览器、广泛应用于各类项目中。然而&#xff0c;随着技术的发展&#xff0c;新的工具不断涌现&#xff0c;Playwright 作为其中的佼佼者&#xff0c;以其现代化的设计和强大的特性吸引了越来越…

828华为云征文|docker部署kafka及ui搭建

1.介绍 1.1 什么是华为云Flexus X实例 最近华为云828 B2B企业节正在举办&#xff0c;Flexus X实例的促销也非常给力&#xff0c;大家可以去看看。特别是对算力性能有要求&#xff0c;同时对自建MySQL、Redis、Nginx性能有要求的小伙伴&#xff0c;千万不要错过。Flexus云服务器…

你都学会栈和队列了赶紧手搓一个对象池吧!!!(超详细,超简单适合新手宝宝学习)

前置知识&#xff1a;en造数据结构与算法C# 用数组实现个栈还不简单&#xff1f;&#xff1f;&#xff1f;看我一秒破之&#xff01;&#xff01;&#xff01;&#xff08;unity演示&#xff09;-CSDN博客 c#有官方造好的关于stack的轮子&#xff0c;建议学习学习拿来直接用 …

揭开OpenAI草莓模型神秘面纱——重塑大语言模型的逻辑能力

OpenAI即将发布“草莓”模型 来源&#xff1a;medium 据报道&#xff0c;OpenAI计划在未来两周内发布其新的AI模型Strawberry&#xff08;草莓&#xff09;。据 Seeking Alpha周二&#xff08;9 月 10 日&#xff09;援引The Information 的一篇付费文章报道&#xff0c;新模型…

Solana核心漏洞技术详解

8月9日&#xff0c;Solana团队齐心协力解决了一个严重的安全漏洞。这次秘密修复详情可以在GitHub上查询到。CertiK团队对这一漏洞进行了深入分析。 1. Solana漏洞起因 8月9日&#xff0c;Solana验证者和客户端团队齐心协力解决了一个严重的安全漏洞。Solana验证者Laine表示&am…

[WUSTCTF2020]颜值成绩

1.测试输入发现存在数字型sql注入 1 and 1 报错 尝试了几个字符&#xff0c;确定空格被过滤了 空格用/**/替换 1/**/and/**/1 构造轮子尝试成功&#xff0c;所以这里要用布尔注入 后面的思路就是比较常规的了&#xff0c;先爆破库名&#xff0c;再爆破表、字段 写了个脚本简…

第四部分:1---文件基础理解、C语言文件操作、Linux系统文件接口、使用一个变量传递多个标志位

目录 文件基础理解&#xff1a; 文件是如何组成的&#xff1f; 对文件操作的本质是什么&#xff1f; 文件被打开的本质是什么&#xff1a; 进程和文件的调度关系解析&#xff1a; 文件被打开后如何被管理&#xff08;文件描述符/文件描述符表&#xff09;&#xff1f; 文…

深度学习——基础知识

深度学习的重点在于优化&#xff0c;其中很重要的步骤在于如何调参&#xff0c;会涉及到一些微积分等数学知识。不同于以往接触到的数值运算&#xff0c;深度&#xff08;机器&#xff09;学习都是关于张量Tensor&#xff08;向量&#xff09;的计算&#xff0c;Python中最常用…

【oj刷题】滑动窗口篇:滑动窗口的应用场景和注意事项

前言&#xff1a; 滑动窗口其实基本原理还是双指针&#xff0c;但在双指针中左右指针可能会有回退操作&#xff0c;而滑动窗口的左右指针只会向前走&#xff0c;不会回退&#xff0c;下面就来讲解一下滑动窗口的概念和具体操作&#xff08;主要是例题讲解&#xff09; 目录 一、…

【 Linux】基础命令及常用小技巧

文章目录 Linux基础命令常用小技巧基本命令pwd : print work directory 打印当前的工作目录cd : change driectory 改变当前工作目录ls: list 查看指定目录下的文件mkdir: make directory 创建目录 文件操作命令查找命令管道命令和过滤命令wc : word count 单词统计echo 输出命…

Hotohiko Sakamoto算法,以及用其计算星期几【算法 15】

探索Hotohiko Sakamoto算法&#xff1a;构建素数排列的奥秘 在算法领域&#xff0c;Hotohiko Sakamoto算法以其独特的构造方式和深刻的数学背景&#xff0c;吸引了众多算法爱好者和研究者的关注。本文将带您一起探索Hotohiko Sakamoto算法的核心思想&#xff0c;了解它是如何构…

深度学习_GPT2Block详解(casual attention)

一、GTP2Block 整体结构 1.1 block准备 import torch from torch import nn from transformers import GPT2Model, GPT2Config from transformers.models.gpt2.modeling_gpt2 import GPT2Blockcfg GPT2Config() print(cfg.add_cross_attention) blk GPT2Block(cfg, layer_…

“汉语新解” Prompt新高度,火爆的李继刚

“汉语新解” prompt 是由李继刚设计的一个用于启发人工智能模型进行创意性文本生成的指令模板。这个 prompt 的设计初衷是为了让AI能够以一种独特的方式解析和重新诠释常见的中文词汇&#xff0c;从而产生出具有深刻洞察力和幽默感的文本内容&#xff0c;仿佛是由鲁迅或林语堂…

Linux线程同步:深度解析条件变量接口

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f351;Linux线程同步&#x1f409;条件变量---实现线程同步&#x1f4a7;同步概念与竞态条件&#x1f406;条件变量接口*初始…

sqli-labs靶场自动化利用工具——第13关

文章目录 概要整体架构流程技术细节执行效果小结 概要 Sqli-Labs靶场对于网安专业的学生或正在学习网安的朋友来说并不陌生&#xff0c;或者说已经很熟悉。那有没有朋友想过自己开发一个测试脚本能实现自动化化测试sqli-labs呢&#xff1f;可能有些人会说不是有sqlmap&#…

每日OJ_牛客_马戏团(模拟最长上升子序列)

目录 牛客_马戏团&#xff08;模拟最长上升子序列&#xff09; 解析代码 牛客_马戏团&#xff08;模拟最长上升子序列&#xff09; 马戏团__牛客网 搜狐员工小王最近利用假期在外地旅游&#xff0c;在某个小镇碰到一个马戏团表演&#xff0c;精彩的表演结束后发现团长正和大…