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)
\ddd1到3位八进制数所代表的任意字符
\xhh1到2位十六进制所代表的任意字符

占位字符

image20201222124236020.png

关键字与保留标识符

关键字

变量常量命名不能使用

32个关键字

image20210816093545748.png

标识符

  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;

常量

类型

  • 整型常量: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
数据类型字节取值范围
char1-128~127
unsigned char10~255
short2-32768~32767
unsigned short20~65535
int4-2147483648~2147483647
unsigned int40~4294967295
long4-2147483648~2147483647
unsigned long40~4294967295
long long8-9223372036854775808~9223372035854775807
unsigned long long80~18446744073709551615
float4$1.1754910^{-38}~3.4028210^{38}$
double8$2.2250710^{-308}~1.7976910^{308}$
long double12$2.2250710^{-308}~1.7976910^{308}$

字符和字符串

ASCII编码表

数据类型字节数取值范围
signed char1-128~127
unsigned char10~255
short2-32768~32767
unsigned short20~65535
int4-2147483648~2147483647
unsigned int40~4294967295
long4-2147483648~2147483647
unsigned long40~4294967295
long long8-9223372036854775808~9223372036854775807
unsigned long long80~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+38
-减法运算符(双目)5-32
*乘法运算符(双目)5*315
/除法运算符(双目)5/31
%求余运算符(双目)5%32
+正号运算符(单目)+55
-负号运算符(单目)-5-5

%不能将浮点数进行取余

image20200806071721188.png

表达式

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

    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
||逻辑或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;
}

分支结构的嵌套

image20200806121857343.png

根据流程图写代码

悬挂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))

补充

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;

Q.E.D.