当前位置: 首页 > news >正文

《C语言程序设计》琐碎知识点总结笔记

《C语言程序设计》琐碎知识点总结笔记

本篇笔记旨在拾掇干净一些琐碎的小/冷知识点,免得给之后的学习留不必要的念想。

一、变量的存储类别

变量的定义形式:

[存储类别] 类型标识符 变量名

现对“存储类别”加以说明。

存储空间分为程序区数据区数据区分为静态存储区动态存储区

存储类别有:自动型(auto)、寄存器型(register)、静态型(static)、外部型(extern)。

1.局部变量的存储类别

局部变量的存储类别有:自动型、静态型、寄存器型。

(1)自动型局部变量

动态存储区分配存储空间,调用函数时分配存储空间,调用结束后自动释放存储空间。

默认的存储类别,相当于最常使用的、定义时不加“存储类别”的变量。

auto float m;

auto int a,b,c=10;

(2)静态型局部变量

静态存储区分配存储空间,调用函数时分配存储空间,调用结束后不会释放存储空间,并保留变量的值

人话:只记住初始化的值,之后的一切变量值的改变都无视。

static int c=3;

上述代码中变量c的值便永远是3了(在其作用域内)。

(3)寄存器型局部变量

将局部变量的值放在CPU通用寄存器中。

只有自动型局部变量和形式参数可以说明为寄存器型变量。(说明寄存器型满足自动型的特性,如可改变值)

register int a,b;

ps:曾见过有人将循环语句中的 \(i\) 声明为寄存器型来进行常数优化,但我的C语言老师又说寄存器型已经“名存实亡”,由此可见还是不要随便用寄存器型为好。

2.全局变量的存储类别

通过引用声明可以扩展全局变量的作用域(类似于函数的引用说明),引用声明的形式为:

extern 数据类型 变量名

全局变量的存储类别有:静态型、外部型。

(1)静态型全局变量

静态型全局变量只能被它所在文件中的函数使用,不能被其他文件中的函数使用。

可以通过引用声明本文件内扩展其作用域。

举例如下:

extern int a,b;// a,b的引用说明语句
int fun()
{if(a>b) return a;else return b;
}
static int a,b;// a,b的定义语句

上述代码也可直接写成:

static int a,b;
int fun()
{if(a>b) return a;else return b;
}

(2)外部型全局变量

若没有给出存储类别(即前面什么也不加),则定义的变量为外部型全局变量。

通过引用声明,可以将全局变量作用域扩展到定义它之前的函数,也可以扩展到程序中的其他文件

举例如下:

(源文件1)

int a,b;// 定义外部型全局变量a,b

(源文件2)

extern int a,b;// 外部型全局变量引用说明

二、函数的存储类别

函数的定义形式:

[函数存储类别][函数返回值类型]函数名([函数形式参数表])
{函数体说明部分函数功能语句序列[return 表达式;]
}

现对“函数存储类别”加以说明。

根据函数能否被其他源文件的函数调用,函数可以分为内部函数(static)和外部函数(extern)。

1.内部函数

存储类别为static,又称静态函数。

只能被它所在文件中的函数调用。

不同文件中的内部函数可以同名,互不干扰。

static int fun(int a,int b)
{return (a>b?a:b);
}

2.外部函数

存储类别为extern或省略存储类别

既能被它所在文件中的函数调用,也能被其他文件中的函数调用。

如果一个文件要调用另一个文件中定义的外部函数,则在调用函数的文件中一定要对被调用的外部函数进行引用声明

引用声明的形式:

extern 函数名([函数形式参数表])

举例如下:

(源文件1)

#include<stdio.h>
int main()
{extern fun(int a,int b);int a,b;scanf("%d%d",&a,&b);printf("%d\n",fun(a,b));return 0;
}

(源文件2)

#include<stdio.h>
int fun(int a,int b)
{return (a>b?a:b);
}

三、编译预处理

在编译之前进行的处理,以“#”开头。

1.宏定义

宏定义的本质是在程序编译前进行替换。

注意替换后的运算优先级,在必要时使用括号。

(1)不带参数的宏定义

定义与取消定义:

#define 宏名 宏体
#undef 宏名

举例如下:

#define PI 3.1415926

(2)带参数的宏定义

定义与取消定义:

#define 宏名(形参列表) 宏体
#undef 宏名

使用:

宏名(实参列表)

举例如下:

#define s(a,b) a>b?a:b

s(3,4)

宏替换为:3>4?3:4

2.文件包含

#include "文件名"

#include<文件名>

3.条件编译

形式1:

#ifdef 标识符程序段1
[#else程序段2]
#endif

若标识符已经被定义(使用#define 标识符),则对程序段1进行编译,否则对程序段2进行编译。

形式2:

#ifndef 标识符程序段1
[#else程序段2]
#endif

若标识符未被定义,则对程序段1进行编译,否则对程序段2进行编译。

形式3:

#if 常量表达式程序段1
[#else程序段2]
#endif

若表达式的值为真,则对程序段1进行编译,否则对程序段2进行编译。

四、主函数与命令行参数

主函数的格式为:

void main([int argc,char *argv[]])
{...
}

()中的信息称为命令行参数。

argc用于保存用户命令行中输入的命令中参数的个数,命令名本身也是一个参数。

argv[]是一个字符指针数组,用于保存各个参数的首地址(包括命令名本身)。

五、变量的作用域

ps:只提几个关键点。

1.{}括起来的是一个复合语句,其中定义的局部变量只能在该复合语句中使用。

2.主函数中定义的变量也是局部变量,只在主函数中有效。

3.不同函数中定义的局部变量可以同名,它们互不干扰。

4.形式参数也是局部变量,只在它所在的函数中有效。

5.全局变量的作用域从定义点开始直到文件尾,可以被作用域内的所有函数共用。

6.在同一个源文件内,如果全局变量和局部变量同名,则在局部变量的作用域内全局变量不起作用。(强权难压地头蛇)

六、运算符与表达式

1.算术运算符和算术表达式

(1)算术运算符

双目:+加法 -减法 *乘法 /除法 %取模

单目:+取正 -取负 ++自加 --自减

取负不改变变量的值。

自加自减运算符只能用于变量,不能用于常量和表达式。

(2)算术表达式

单个的常量和变量都是算术表达式。

算术表达式的值是数值型。

(3)优先级

高:-(取负)、++、--

中:*、/、%

低:+、-

(4)结合方向

右结合:-(取负)、++、--

左结合:+、-、*、/、%

当++、--、+、-混合运算时,应自左向右尽可能地组合运算符。

(5)类型转换

自动类型转换:从低精度类型转换成高精度类型。

精度从高到低:double->long->unsigned->int->char

强制类型转换

(类型标识符) (表达式)

2.关系运算符和关系表达式

(1)关系运算符

双目:> >= < <= == !=

(2)关系表达式

关系表达式的值只能是1或0,数据类型为整型,代表关系运算结果的真/假。

(3)优先级

高:>、>=、<、<=

低:==、!=

(4)结合方向

均为左结合

3.逻辑运算符和逻辑表达式

(1)逻辑运算符

双目:&&逻辑与 ||逻辑或

单目:!逻辑非

(2)逻辑表达式

逻辑表达式的值:1代表真,0代表假。

若a,b都为真,则a&&b为真,否则为假;

若a,b都为假,则a||b为假,否则为真;

若a为真,则!a为假;若a为假,则!a为真。

(3)优先级

高:!

中:&&

低:||

(4)结合方向

&& ||为左结合,!为右结合。

并不是所有逻辑运算都被执行,只有在必须执行下一个逻辑运算才能求出表达式的值时,才执行该运算。

4.赋值运算符和赋值表达式

(1)赋值表达式

赋值表达式的值就是被赋值的变量的值,赋值表达式的值的类型就是被赋值的变量的类型。

(2)结合方向

赋值运算符的结合方向都是右结合。

a=b=c=10等价于a=(b=(c=10))

赋值允许连等,但定义变量时不允许,错误写法:

int a=b=c=10;

赋值表达式中的赋值运算符的左侧必须是变量,不能是常量和表达式。

5.逗号运算符和逗号表达式

形式:

表达式1,表达式2[,表达式3,...,表达式n]

求解过程:从左到右依次计算每个表达式的值。

逗号表达式的值就是“表达式n”的值,逗号表达式的值的类型就是“表达式n”的值的类型。

6.条件运算符和条件表达式

形式:

表达式1?表达式2:表达式3

表达式1一般为关系表达式或逻辑表达式,表达式2和3同类型。

求解过程:执行表达式1,若表达式1的值非0,则执行表达式2,表达式2的值就是条件表达式的值;若表达式1的值为0,则执行表达式3,表达式3的值就是条件表达式的值

http://www.rkmt.cn/news/132846.html

相关文章:

  • 基于Java+SSM+SSM线上管理系统(源码+LW+调试文档+讲解等)/线上管理平台/在线管理系统/线上管理软件/网络管理系统/线上办公系统
  • 算法:2.复写零
  • ExcalidrawAPI文档配图:接口调用流程展示
  • Day8 出现频率最高的字母 -卡码网C++基础课
  • 基于Java+SSM+SSM短剧推荐系统(源码+LW+调试文档+讲解等)/短剧推荐算法/短剧推荐平台/短剧推荐服务/短剧推荐模型/短剧智能推荐
  • Day2:语言数据类型和变量
  • Excalidraw思维导图玩法:结构化思考新工具
  • Excalidraw常见问题汇总:官方FAQ精华整理
  • 基于径向基函数神经网络RBFNN的自适应滑模控制学习(Matlab代码实现)
  • Excalidraw热力图模拟:用户行为分布示意
  • 递归算法和回溯算法
  • 跟着Datawhale动手学Ollama - TASK4: Ollama 在 LangChain 中的使用
  • 分层模糊系统:梯度下降与递推最小二乘法联合辨识研究(Matlab代码实现)
  • cesium126,240506,Ce for Ue 建筑单体高亮的实现P1-基础染色:
  • Excalidraw用户体验监控:前端性能指标采集
  • Excalidraw类图绘制:面向对象设计辅助
  • 基于Spring Boot技术的数字乡村农作物智慧管理系统设计毕设
  • A server error occurred. Please contact the administrator的问题解决
  • 基于Spring Boot的医院预约挂号系统的设计与实现毕业设计源码
  • PyTorch中通过设置随机种子使训练结果可复现
  • ExcalidrawOKR目标看板:团队目标对齐工具
  • 基于Spring Boot的在线考试系统设计与实现毕业设计
  • 2025年度绵阳高中复读学校口碑推荐榜单,名办高中/学校/实验中学/高中复读学校/中学/实验学校/高中高中复读学校企业怎么选择 - 品牌推荐师
  • 利用 SSI-COV 算法自动识别线状结构在环境振动下的模态参数研究(Matlab代码实现)
  • 精品UI知识付费系统源码 响应式视频教程知识付费软件下载网站模板
  • 基于Spring Boot的新生报到管理系统的设计与实现毕业设计源码
  • ATTCK实战系列(一)红日靶场1
  • Excalidraw CI/CD流水线搭建:代码变更自动部署
  • 蓝凌EKP产品:一次 Hibernate 乐观锁 + 死锁的深度踩坑实录
  • Excalidraw负载均衡配置:高并发场景下的稳定性保障