C语言基础

概述

main函数

main函数是C语言的主函数,每个C语言程序都必须存在一个main函数,因为在程序开始的时候就会调用,它是程序执行的起点,当main函数的类型为int的时候表示函数返回一个整数值,类型为VOID表示函数不接受任何参数。main函数的函数体包括左花括号和右花括号之间的任何内容。

printf函数

printf()函数是格式化输出函数,一般用于向标准输出设备按规定格式输出信息

printf()函数的调用格式为:printf("<格式化字符串>, <参量表>")

格式输出,它是c语言中产生格式化输出的函数(在stdio.h中定义)。用于向终端(显示器、控制台等)输出字符。格式控制由要输出的文字和数据格式说明组成。要输出的文字除了可以使用字母、数字、空格和一些数字符号以外,还可以使用一些转义字符表示特殊的含义。主要包括%d, %o, %x, %g, %c, %s, 以及换行符\n

空白与注释

空白在C语言里并没有什么特殊的约定来限制你的使用,它的作用仅仅只是似的程序更好理解,更好的显示出程序的结构,仅此而已

在C语言里存在以下两种注释方式

  1. // 单行注释
  2. /*多行注释*/

基础介绍

运行机制:C语言–> 汇编语言–>机器语言–>CPU

编译型语言VS解释性语言

  • 编译型语言:编译为可执行文件,直接由CPU执行
  • 解释型语言:编译为字节码,由解释器交给CPU执行

程序执行

  1. 编写
  2. gcc test.c -o test编译
  3. ./test执行

格式化输入

#include <studio.h>
int main(){
	printf('hello world');
    return 0;
}

输入输出函数

输入函数 scanf("%?", temp);

输出函数 printf("%?", temp);

转义字符

转义字符 含义
\a 响铃(BEL)
\b 退格(BS),将当前位置移到前一列
\f 换页(FF),将当前位置移到下页开头
\n 换行(LF),将当前位置移到下一行开头
\r 回车(CR),将当前位置移到本行开头
\t 水平制表(HT),跳到下一个TAB位置
\v 垂直制表
\\ 表示(\)
\' 表示()
\" 表示()
\? 表示(?)
\0 表示空字符(NULL)
\ddd 1到3位八进制数所代表的任意字符
\xhh 1到2位十六进制所代表的任意字符

占位字符

image-20201222124236020

关键字与保留标识符

关键字

变量常量命名不能使用

32个关键字

image-20210816093545748

标识符

  1. 以下划线开始的标识符,例如:

    _Bool_Complex_Imaginary

  2. 语言标准库函数名,例如:

    printf() scanf() strlen() strcpy()

命名规则

匈牙利命名法

  • 变量名前,加上属性、类型

  • 变量命名有意义

  • 驼峰命名法

    • 大驼峰命名法

      所有单词全部首字母大写

    • 小驼峰命名法

      除了第一个单词小写外,其他的单词首字母大写

变量常量

变量

变量的意义就算确定目标并提供存放的空间

变量名

  • 变量名只能三英文字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成
  • 第一个字母必须三字母或者下划线开头
  • 变量名区分大小写

数据类型

  • char

    字符型,占用一个字节

  • int

    整型,通常反映了所用机器中整数的最自然长度

  • float

    单精度浮点型

  • double

    双精度浮点型

声明变量的语法

int a;
char b;
float c;
double d;

变量赋值方式

方式一:

int a, b, c;
a = 1;
b = 2;
c = 3;

方式二:

int a = 1;
int b = 2;
int c = 3;

方式三:

int a = 1, b = 2, c = 3

常量

类型

  • 整型常量:520,1314,123
  • 实型常量:3.14,5.12,8.97
  • 字符常量
    • 普通字符:‘L’,‘o’,‘v’,’e‘
    • 转义字符:‘\n’,’\t‘,‘\b’
  • 字符串常量:“FishC”

定义符号常量

  • 格式:#define 标识符 常量

  • 比如:

    #define URL 'http://www.fishc.com'
    

    一般用小写字母命名变量,用大写字母命名常量

    标识符

    命名规则同变量的命名规则 [[C-basic#变量|变量]]

字符串常量

  • 字符:‘F’, ’i’, ‘s ‘ , ‘h’ , ‘C’

  • 字符串:

    • “Hello world”
    • “I love FishC.com!”

    编译过程中会将字符串最后一个字符后面添加一个\0的空字符,用于判断字符串结束

数据类型

  • 基本类型

    • 整数类型int

      short int <= int <= long int <=long long int

    • 浮点数类型float double

      float

      double

      long double

    • 字符类型char

    • 布尔类型 _Bool

      C99之前C语言没有布尔类型,需要引用#include <stdbool>

    • 枚举类型enum

  • 指针类型 type *

  • 构造类型

    • 数组类型
    • 结构类型 union
    • 联合类型 struct
  • 空类型

整型

signed和unsigned

signed:可以储存负值

unsigned:只能储存正值及0

[signed] short [int];
unsigned short [int];
[signed] int;
unsigned int;

取值范围

二进制

  • 比特位

    CPU能读懂的最小单位——比特位,bit,b

  • 字节

    内存机构的最小寻址单位——字节,Byte,B

    1 Byte == 8 bit

    计算技巧 $2^n-1$

符号位

  • 存放signed类型的存储单元中,左边第一位表示符号位。如果该位为0,表示该整数是一个正数;如果该位为1,表示该整数是一个负数
  • 一个32位的整型变量,除去左边第一位符号位,剩下表示值的只有31个比特位
  • 事实上计算机是用补码的形式来存放整数的值
    • 正数的补码三该数的二进制形式
    • 负数的补码需要通过以下几步获得:
      1. 先取得该数的绝对值
      2. 再将第1步的值按位取反
      3. 最后将第2步的值加1
数据类型 字节 取值范围
char 1 -128~127
unsigned char 1 0~255
short 2 -32768~32767
unsigned short 2 0~65535
int 4 -2147483648~2147483647
unsigned int 4 0~4294967295
long 4 -2147483648~2147483647
unsigned long 4 0~4294967295
long long 8 -9223372036854775808~9223372035854775807
unsigned long long 8 0~18446744073709551615
float 4 $1.1754910^{-38}~3.4028210^{38}$
double 8 $2.2250710^{-308}~1.7976910^{308}$
long double 12 $2.2250710^{-308}~1.7976910^{308}$

字符和字符串

ASCII编码表

数据类型 字节数 取值范围
signed char 1 -128~127
unsigned char 1 0~255
short 2 -32768~32767
unsigned short 2 0~65535
int 4 -2147483648~2147483647
unsigned int 4 0~4294967295
long 4 -2147483648~2147483647
unsigned long 4 0~4294967295
long long 8 -9223372036854775808~9223372036854775807
unsigned long long 8 0~18446744073709551615

字符串一般不会默认unsigned

// 声明字符串:
char name[5];
// 给字符串赋值:
name[0] = 'F';
name[1] = 'i';
name[2] = 's';
name[3] = 'h';
name[4] = 'C';
// 定义字符串:
char name[5] = {'F','i','s','h','C'};

类型转换

小坑位数据会转变为大坑位数据

#include <stdio.h>

int main()
{
    printf("整型输出:%d\n",1+(int)1.8);// 类型强制转换
    printf("浮点型输出:%f\n",1+2.0);
    
    return 0;
}

运算符

算术运算符

C语言通过提供运算符来支持我们对数据进行处理

算术运算府

运算符 名称 例子 结果
+ 加法运算符(双目) 5+3 8
- 减法运算符(双目) 5-3 2
* 乘法运算符(双目) 5*3 15
/ 除法运算符(双目) 5/3 1
% 求余运算符(双目) 5%3 2
+ 正号运算符(单目) +5 5
- 负号运算符(单目) -5 -5

%不能将浮点数进行取余

image-20200806071721188

表达式

  • 用运算符和括号将操作数连接起来的式子,我们称之为表达式

    1+1;
    'a'+'b';
    a+b;
    a+'b'+pow(a,b)*3/4+5;
    

    运算符存在怕优先级

关系运算符

  • 使用关系运算符来比较两个数的大小关系:

    优先级相同(高)

    <(小于)

    < = (小于或等于)

    > (大于)

    优先级相同(低)

    == (等于)

    != (不等于)

关系表达式

  • 用关系运算符将两边的变量、数据或表达式连接起来,称之为关系表达式:

    1<2;
    a<b;
    a<=1+b;
    'a'+'b'<='c';
    (a=3)>(b=5);// 只会返回一个布尔值
    
  • 关系表达式得到的值是一个逻辑值,即真或假,在C语言的逻辑运算中,用数字1表示真,用数字0表示假

逻辑运算符

运算符 含义 优先级 举例
! 逻辑非 !a
&& 逻辑与 a&&b
` ` 逻辑或

逻辑与,参与的所有表达式,结果全部为真,才为真,只要有一个为假,就为假

逻辑或,参与的所有表达式中,只有一个结果为真,结果就为真,所有的都为假,才会为假

逻辑表达式

用逻辑运算符将两边的变量、数据或表达式连接起来,称之为逻辑表达式

短路求值

  • 短路求值又称最小化求值,是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值
  • C语言对于逻辑与和逻辑或采用短路求值的方式

位运算符

运算符 功能
&
|
^ 异或
~ 取反
» 左移
« 右移

赋值运算符

运算符 功能
= 赋值
+= 加法且赋值
-= 减法且赋值
*= 乘法且赋值
/= 除法且赋值
%= 取余且赋值
»= 左移且赋值
«= 右移且赋值
&= 按位与且赋值
|= 按位或且赋值
^= 按位异或且赋值
int a;
a = 5;

赋值运算符的左边必须是一个lvalue,变量名就是lvalue

复合的赋值运算符

int a;
a+=1;
a-=1;
a*=1;
a/=1;

自增自减运算符

int a;
a++;
++a;
a--;
--a;

其他运算符

sizeof运算符

sizeof运算符

sizeof运算符用于获得数据类型或表达式的长度

sizeof(object); //sizeof(对象);
sizeof(type_name); // sizeof(类型);
sizeof object; // sizeof 对象

条件运算符

  • 语法:exp1?exp2:exp3;
    • exp1是条件表达式
    • 如果结果为真,返回exp2
    • 如果结果为假,返回exp3

真左假右

逗号运算符

  • 语法:表达式1,表达式2,……,表达式n
    • 逗号表达式的运算过程为从左往右逐个计算表达式
    • 逗号表达式作为一个整体,它的值为最后一个表达式(也即表达式n)的值
  • a = (b = 3, (c = b + 4 ) + 5)
    • 先将变量b赋值为3
    • 然后变量c赋值为b+4的和,也就是7
    • 接下来把c的值加上5
    • 最后赋值给变量a,得到变量a的值是12

运算符优先级

优先级 运算符 结合律
1 后缀运算符:[] () · -> ++ –(类型名称){列表} 从左到右
2 一元运算符:++ – ! ~ + - * & sizeof_Alignof 从右到左
3 类型转换运算符:(类型名称) 从右到左
4 乘除法运算符:* / % 从左到右
5 加减法运算符:+ - 从左到右
6 移位运算符:« » 从左到右
7 关系运算符:«= »= 从左到右
8 相等运算符:== != 从左到右
9 位运算符 AND:& 从左到右
10 位运算符 XOR:^ 从左到右
11 位运算符 OR:| 从左到右
12 逻辑运算符 AND:&& 从左到右
13 逻辑运算符 OR:|| 从左到右
14 条件运算符:?: 从右到左
15 赋值运算符: = += -= *= /= %= &= ^= |= «= »= 从右到左
16 逗号运算符:, 从左到右

逻辑结构

C语言中,包括三种执行流程

  1. 顺序结构,所谓的顺序结构呢,就是从上往下顺序的执行
  2. 选择结构,就是给出一个条件,如果条件符合,去哪里执行,不符合,又去哪里执行
  3. 循环结构,循环结构呢,就是重复执行某一段代码

分支结构

if语句

// if 语句(1)
if(表达式)
{
    ......// 逻辑值为真所执行的语句、程序块
}
// if 语句(2)
if(表达式)
{
    ......// 逻辑值为真所执行的语句、程序块
}
else
{
    ......// 逻辑值为假所执行的语句、程序块
}
// if 语句(3)
if(表达式1){......}
else if(表达式2){......}
else if(表达式3){......}
.
.
.
else if(表达式n){......}
else{......}

switch语句

break语句

switch(表达式)
{
    case 常量表达式1:语句或程序块1;break;
    case 常量表达式2:语句或程序块2;break;
    ......
    case 常量表达式n:语句或程序块n;break;
    default:语句或程序块n+1;break;
}

分支结构的嵌套

image-20200806121857343

根据流程图写代码

悬挂else问题else会匹配最近的if

解决:{}

循环结构

while语句

// while语句 入口条件循环
while(i<=100) 
{
    sum = sum +i;
    i= i + 1;
}
// do...while语句 出口条件循环
do{
    sum = sum + i;
    i = i + 1;
}
while(i<=100);

for循环

for(表达式1;表达式2;表达式3){
    循环体
}

三个表达式用分号隔开,其中:

  • 表达式1是循环初始化表达式
  • 表达式2是循环条件表达式
  • 表达式3是循环调整表达式

灵活的for语句

  • 表达式1,表达式2和表达式3可以按照需要进行省略(但分号不能省)
  • 表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式(即用逗号分隔多个表达式)
  • C99允许在for语句的表达式1中定义变量

循环嵌套

先执行内部循环再执行外部循环

跳出循环

break语言

跳出循环

continue语言

跳出本轮循环

只能作用于一层循环

预处理

宏(Macro)是预处理命令的一种,它允许用一个标识符来表示一个字符串。

define

#define nNum 15
#define ADD (a+b)
#define MAX(a,b) ((a>b)?(a):(b))

undef

取消宏处理

条件编译

#ifdef RKVIR
	printf("this is def");
#else
	printf("this is else");
#endif
#define SYS 2

#if SYS == 1
	printf("1");
#elif SYS == 2
	printf("2");
#endif

标准库

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

C的标准库

Header File Content
stdio.h 输入和输出
stdlib.h 最常用的一些系统函数
string.h 字符串处理
math.h 数学函数
ctype.h 字符类测试
time.h 时间和日期
stdarg.h 可变参数列表
signal.h 信号
assert.h 断言
setjmp.h 非局部跳转
errno.h 定义错误代码
stddef.h 一些常数、类型和变量
locale.h 本土化
float.h 浮点数运算
limits.h 定义整数数据类型的取值范围

补充

go to语句

类似于汇编语言的JMP

  • 语法:goto标签;
#include <stdio.h>

int main()
{
    int nNum = 0;
loop:
    printf("%d\n", nNum);
    nNum++;
    goto loop;
    return 0;
}

尽量永远不要用到

不建议使用

typedef

定义类型的别名

typedef int uint32;
typedef DATEBASE_CLASS_ONE DCO;