C 语法入门
GNU/Linux(64位)+ GCC_11.2.0
数据类型
4 种基本数据类型
数据类型 | 中文名称 | 所开辟的存储空间的大小(Byte) |
---|---|---|
int | 整型 | 4 |
float | 单精度浮点型 | 4 |
double | 双精度浮点型 | 8 |
char | 字符型 | 1 |
4 种限定符(施加于基本数据类型)
short
、long
、signed
、unsigned
signed 和 unsigned 用于限定所有整型和字符型(包括被 short 或 long 限定了的整型)
给数据类型起别名,使用 typedef
sizeof 根据数据类型获取数据元素所占内存空间的字节数
1 | sizeof( ElemType ); |
变量
可将变量理解为存储数据的容器
变量的命名规则
- 字母或下划线开头,可包含数字
- 字母严格区分大小写
- 以下划线开头的变量名是有可能和系统定义的变量名冲突的
- 拒绝使用关键字和保留字
变量的声明 & 初始化
1 | int foo; // 声明变量 |
变量的声明和初始化可合二为一
1 | int foo2 = 2; |
只声明不初始化的变量其所在内存是脏的
常量
一旦初始化,则其值无法被改变的量
字符常量
字符 + 单引号 <=> 字符常量
字符常量参与运算时,实际上是其对应的 ASCII 码参与运算
1 | printf("%d\n", 1 + '0'); // 49 |
字符串常量
请参考这里
运算符与表达式
算术运算符
+
、-
、*
、/
、%
++
、--
、
赋值运算符
+=
、-=
、*=
、/=
、%=
=
关系运算符
==
、!=
、>
、>=
、<
、<=
逻辑运算符
&&
、||
、!
位运算符
按位与&
、按位或|
、按位异或^
、按位取反~
「左移<<
、右移>>
」=> 保持符号位不变 !
如果你想看二进制,可以使用 C++ 的 bitset
eg:
1 | short int a = 6; |
三目运算符
expression1 ? res1 : res2
类型转换
在同一表达式中出现不同类型变量时,为了得出更精确或更能描述实际情况的结果
表达式中的变量们会根据某种规则,统一转换成某种类型
自动的类型转换
数据位短的类型会向数据位长的类型转换(可使用 C++ 的 typeid()验证)
相比于 int,unsigned int 的数据位多一个
char 和 short int 统一向 int 转换
1 | short int a = 1; |
有可能损失数据精度
1 | float a = 100.5f; |
控制
条件判断
1 | if (表达式1) { |
一个良好的代码风格是:永远都加上花括号,即使只有一行代码。
循环
1 | // 当循环次数不确定,较适合用 while 循环 |
函数
1 | // 对于无参函数,参数列表建议写为 void |
返回值类型默认为整型
抽象、封装、复用
开发者得以将更多时间用于专注业务逻辑的实现
作用域
除全局作用域外,一个花括号就能形成一个作用域
结论:
外层作用域无法访问内层作用域
内层作用域可以访问外层作用域
生存期
1 | int foo() { |
静态变量
相当于拥有局部作用域的全局生存期变量
指针
指针与 const
https://liupj.top/2021/11/18/pointer&const/
指向函数的指针
1 | int add(int a, int b) { |
递归
1 | // 直接递归(形式上是自调用)+ 单递归入口 |
1 | // 直接递归(形式上是自调用)+ 多递归入口 |
代码优化思路:将全局变量 i 改为静态变量,放到 r() 的函数体中,以获得更好的封装性和可读性
本文不介绍间接递归
数组
数组的声明与初始化
1 | int arr[4] = { 1, 2, 3, 4 }; |
1 | int arr[4] = { 0 }; |
数组与指针
https://liupj.top/2022/04/05/array&pointer/
结构体
数组中元素的数据类型相同,结构体中元素的数据类型可以不同
1 | struct { |