欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言的学习整理

程序员文章站 2022-03-14 08:41:36
·DAY_1 C语言数据类型 #import 导入框架,框架下包含了很多方法以及函数 main() 主函数:程序的出口和入口 一、数据类型 数据类型 所占...

·DAY_1 C语言数据类型

#import

导入框架,框架下包含了很多方法以及函数

main()

主函数:程序的出口和入口

一、数据类型

数据类型 所占字节数 英文

字符型 1 char

整型 4 int

长整型 4/8 long

短整型 2 short

单精度浮点型 4 float

双精度浮点型 8 double

long所占的字节数跟操作系统位数有关,32位占4个字节,64位占8个字节。

字节数:所能表示的最大数,最小数范围不一样

二、常量,变量

常量:程序运行期间值不能被改变

变量:程序运行期间值能够被改变。

是一个容器(存储区域),值就是容器里面的内容。

变量的定义

语法:变量类型 变量名 = 初值;

定义一个整型变量:int a = 0;

定义一个浮点型变量:float b = 1.01;

定义一个字符型变量:char c = ‘a’;

打印输出

printf(“%d,%f,%c”,a,b,c);

变量名的命名规范:

1、在同一个作用域内不能重命名

2、由数字,字母,下划线组成,但是不能以数字开头

3、见名知意

4、不能与系统保留字同名

三、运算符

1、赋值运算符 =

2、算术运算符

+(加),-(减),*(乘);

/(除,取整,除数不能为0);

%(取余,取余符号两边都为整数)

++(自增),- -(自减)

3、复合运算符

+=,-=,*=,/=,%=

a += 1相当于a = a+1

a -= 1 相当于a = a-1

a *= 2 相当于a = a*2

a /= 2 相当于a = a/2

a %= 2 相当于a = a%2

四、表达式,语句

语句以分号结尾

表达式:由常量,变量,运算符组成的式子就是表达式(不以分号结尾),其中两项可以为空

五、格式化输入输出函数

输出函数语法格式:

printf(“格式串”,表达式);

格式串由转换字符和字符串组成

转换符:整型 %d

短整型 %hd

长整型 %ld

浮点型 %f

字符型 %c

字符串 %s

去掉小数点后无效0 %g

地址 %p

所占内存空间 %lu

转义字符

换行 :\n

打印% :%%

打印\ : \\

格式化输入函数

scanf(“格式串”,&表达式);

在同一个scanf内输入两个整型数,需要用空格或者逗号隔开。

格式串里面不建议加任何字符或者字符串

在同一个scanf内输入两个字符,不需要隔开

·DAY_2 C语言分支结构

一、布尔类型

bool类型:是一种非真即假(非0即真)的数据类型(不是YES,就是NO)

BOOL y = yes;

BOOL n = no;

二、关系运算符

>(大于),<(小于),>=(大于等于),<=(小于等于),!=(不等于),==(等于)

三、逻辑运算符

&&(与) 一假即假,全真即真

||(或) 一真即真,全假即假

!(非) 取反

逻辑与的短路情况

将容易为假的结果放在&&符号的左侧,效率更高

逻辑或的短路情况

将容易为真的结果放在||符号的左侧,执行效率更高

四、分支结构

if语句一般用来表示一种情况

语法格式:

if (表达式){

表达式为真执行的代码;

}

if else语句适用于两种情况的判断

语法格式:

if (表达式){

表达式为真执行此代码1;

}else{

表达式为假执行此代码2;

}

if级联式适用于多种(大于2)情况的判断

语法格式:

if (表达式1){

表达式1为真执行此语句

}else if (表达式2){

表达式2为真执行此语句

}else{

表达式1和表达式2都为假,执行此语句

}

四、条件运算符

如果式1 > 式2为真,返回式3的值,否则返回式4的值

语法格式:

表达式1 > 表达式2 ? 表达式3 : 表达式4;

五、switch case语句

语法格式

switch (整型表达式){

case 整型常量1:

如果表达式的值等于整型常量1,执行此语句1;

break;

case 整型常量2:

如果表达式的值等于整型常量2,执行此语句2;

default :

当表达式的值不等于上面任何一个常量值的时

候,执行此语句;

break;

}

break用来跳出switch语句

switch case和if else的适用环境有所区别:

switch case用于某个点的判断,更加清晰明了

if else用于某个分段的判断

六、枚举

关键字:enum

枚举:列举出所有的可能性情况

语法格式:

枚举类型关键字 枚举名{

枚举值1,

枚举值2,

……

};

枚举名可以省略

枚举值是具有符号名称的整型常量

第一个枚举值默认为0,依次递增

枚举值2设为100,不会改变之前的枚举值,但可以改变之后的枚举值

·DAY_3 C语言循环结构

循环结构定义:满足特定条件下,重复执行的语句(循环体)

一、for循环

语法格式:

for (变量的初始化; 循环条件; 循环增量) {

重复执行的语句(循环体);

}

二、随机数

产生一个随机数:[min max];

语法格式:arc4random() % (max - min + 1) + min;

三、break;continue

break用于switch语句,可以跳出switch语句。

break用在循环语句时,break后面的语句不会被执行,跳出本层循环,向下执行。

continue在循环中,continue后面的语句不会被执行,结束本次循环,向上执行。

四、循环嵌套

外层循环决定行数,内层循环决定具体实现

外层循环变化一次,内层循环变化n次(n由内部循环的循环条件决定)

五、while循环

语法格式:

while (循环条件){

循环体(重复执行的代码)

循环增量增加或减少

}

while循环通常用于不知道循环次数的情况下。

六、do while循环

语法格式:

do {

循环体(重复执行的代码语句)

}while (循环条件);

无论满不满足循环条件,都能执行一次

·DAY_4 C语言数组

一、数组

定义:相同类型的数据的集合,属于构造类型

定义语法:

数据类型 数组名[常量] = {初值1,初值2,......};

定义一个整型数组

第一种定义语法

int arr[4] = {1,2,3,4};

中括号里的4代表数组里面存放的整型数据个数为4个

第二种定义语法

int arr[4] = {1};

当初值个数少于中括号给定的元素个数,那么默认为0

第三种定义语法

int arr[] = {11,22,33};

当中括号内不给定元素个数,那么元素个数和初值个数保持一致,上面数组元素个数为3

二、数组元素的访问

访问语法:数组名[下标];

下标从0开始

可以用循环遍历数组中的每个元素

运算符:sizeof(计算所占内存空间)

格式 sizeof(表达式or类型)

求数组元素的个数

数组元素个数 = 数组所占的内存空间 / 数组中一个元素所占的内存空间

数组名是一个常量地址,数组首元素的地址

三、数组排序

冒泡排序

冒泡排序的核心思想:相邻的两个数两两比较,每一趟比较产生一个最大数,下一趟不参与比较。因此随着比较趟数的增加,每一趟比较次数减少。

语法格式

外层循环控制趟数

for(int i = 0;i < count-1;i++){

内层循环控制次数

for(int j = 0;j < count -i-1;j++){

if(arr[j] > arr[j+1]){

int temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

}

}

}

四、字符串数组

定义字符串数组第一种格式:

char arr[] = {‘a’,’d’,’d’,’c’,’c’};

第二种格式:

char arr[] = “addcc”;

char arr[5] = “12345”;(定义错误,下标越界)

字符串以 \0 结尾

字符串是字符数组,字符数组不一定是字符串

字符串用%s打印,但字符数组我们用循环%c打印

字符串四个常用的函数

求长度函数 strlen()

求字符串中有多少个字符

拷贝函数 strcpy()

将后面一个字符串拷贝给前面一个字符串

前面一个字符串的内存空间要足够容纳下后面的字符串

连接函数 strcat()

将后面一个字符串拼接到前面一个字符串上

前面一个字符串的内存空间要足够容纳下两个字符串

比较函数 strcmp()

比较两个字符串,如果前面比后面大,打印正数;相等打印0,小于打印负数。

单个单个字符比较,一旦前面的字符不等,则得出比较结果,不再比较后面的字符。

五、宏定义:直接替换

宏命名:全部大写或者驼峰命名法

#define PI 3.14

有参宏(尽量多的加括号,保证优先级)

#define SUM(A,B) ((A)+(B))

·DAY_5 C语言函数

函数:具有特定功能的代码段

一、函数定义

函数分类:库函数(main,printf...),自定义函数

自定义函数分为四种:

函数不能嵌套定义(实现)

函数定义语法(函数实现)

返回值类型 函数名(参数列表){

特定功能的代码段(函数体)

}

1、无参无返回值函数定义

void print (void){

printf (“Hello world!\n”);

}

void代表返回值为空,不能省略

print代表函数名

小括号里面代表参数列表,不写代表参数为空,因此void可以不写

大括号里是函数的特定功能实现。

函数无返回值的时候,可以给也可以不给返回值

2、无参有返回值函数定义

int max (){

return 10;

}

函数有返回值的时候,一定要用return返回值;

去掉变量名大括号,剩下来的就是函数类型

类型:无参数,有一个整型返回值的函数

3、有参无返回值函数定义

void print (int a,int b){

printf (“Hello world!\n”);

}

有两个参数,两个都是整型,无返回值的函数

定义参数类型时要一个一个定义,中间用逗号隔开

4、有参有返回值函数定义

int print (int a,int b){

return a+b;

}

函数返回a+b的值

二、函数调用

函数可以嵌套调用,但是不能嵌套实现

调用语法:函数名(参数列表);

调用规则:

1、有返回值,定义相同类型的变量来接收返回值;无返回值不用接收

2、有参数,给定相同类型的参数;无参数,可以不给参数,但是小括号不能省略

三、函数声明

函数声明即在函数定义的基础上,去掉大括号以及里面的内容加上分号

语法:返回值类型 函数名 (参数列表);

当函数定义出现在函数调用之后的时候,需要函数声明;否则,可以省略,但是一般不省略!

四、形参和实参

形参:出现在函数定义里面,称之为形参

实参:出现在函数调用里面,称之为实参

实参向形参传递参数是单向的值拷贝过程

五、函数的嵌套调用

函数可以嵌套调用,但是不能嵌套实现

·DAY_6 C语言结构体

一、声明结构体

构造类型

数组:由相同数据类型组成的一个集合

结构体:由不同数据类型组成的一个集合

struct是结构体的一个关键字

声明一个结构体类型

struct 结构体名{

数据类型 成员名1

数据类型 成员们2

数据类型 成员们3

……

};

结构体类型:struct 结构体名

二、定义结构体变量

第一种:(结构体变量定义和结构体声明分开)

语法:struct 结构体名 变量名 = {对应赋初值};

第二种:(结构体声明和结构体变量定义写在一起)

语法:struct 结构体名 {

成员变量

……

}变量名 = {对应赋初值};

三、结构体变量成员的访问

访问语法:变量名.成员名

四、为结构体类型取别名(重定义)

语法:typedef 旧名字 新名字;

五、匿名结构体

匿名结构体:没有结构体名的结构体

匿名结构体因为没有结构体名,因此定义匿名结构体变量一般直接在声明的时候就进行定义。

六、结构体所占内存空间

分配原则:自上而下分配内存空间;当上一个成员被分配的内存空间足够下一个成员适用,则下一个成员不需要分配内存;每次分配一个最大数据类型的字节空间;总字节空间为最大数据类型的整数倍

七、结构体嵌套

结构体嵌套,成员变量的成员变量访问

变量名.嵌套的结构体变量名.成员名

八、结构体数组

·DAY_7 C语言指针

内存地址:内存中的编号就是内存地址

字节是最小的存储单位

一、指针:就是地址

整型变量:用来存储整型数据的变量

指针变量(指针):用来存储地址的变量

指针的定义语法

类型修饰符 *指针名 = 初值(地址,一般给NULL);

二、指针使用

取地址符 &

p的重新赋值称为指针的重指向

int *p = &c;

取值运算符 *

*p = 20;

三、指针所占的字节数

指针所占的字节数只与操作系统位数有关,与指针类型无关

四、指针的运算:++,- -

地址只有加减,没有乘除

指针加一指加指针类型所占的字节数

五、指针变量和数组的关系

数组名是一个常量地址

数组名arr代表数组首元素地址(&arr[0])

对应关系

arr[0] p[0] *(arr+0) *(p+0)

arr[1] p[1] *(arr+1) *(p+1)

结论:去*加中括号,去中括号加*

六、数组名和指针的区别

数组所占的字节数与数组的类型以及元素个数有关

指针所占的字节数只与操作系统位数有关

七、&arr+1与&arr[0]+1

&arr+1():一次性加一个数组(arr)所占内存空间的字节数

&arr[0]+1:一次性加一个数组元素(arr[0])所占的内存空间

八、数据类型不匹配

short arr[] = {1,2,3};

读取arr[0]的低八位

char *p = arr;

int *q = arr;

九、字符数组与指针

打印字符串,只需要打印字符串对应的地址即可;

打印字符,就是对字符串取值(对字符串对应地址取值)

十、指针数组

整型数组:整型元素的集合

指针数组:指针的集合(数组里存放的是指针)

·DAY_8 C语言内存管理

一、内存区的划分

按地址从小到大分为五个区,分别是代码区,常量区,静态区(全局区),堆区,栈区。

1、代码区:用来存放代码的二进制文件,例如函数(main,sum)

2、常量区:存放常量,只可读,不可以被修改

3、静态区(全局区):静态区的变量从程序开始运行就存在,一直到程序退出才会被释放,这里的全局说的是生命周期。静态区的变量只会被初始化一次。

静态变量即static修饰的变量先于main函数执行

4、堆区:唯一一个由程序员自己申请内存,自己释放内存的区域

内存申请函数:malloc,calloc,realloc;

void*代指泛型指针,如stu*,int*,char*

内存申请函数:malloc

函数声明(函数原型):void* malloc (size_t);

对内存释放函数:free(void*)

函数声明(函数原型):void free (void*);

这里的释放指的是标记删除(释放所有权)

释放内存后的安全操作,指向空区域

int *p = malloc(8);

free(p);

p = NULL;

堆内存分配函数:calloc(size_t,size_t)

函数原型:void* calloc(size_t,size_t);

与malloc的区别:分配空间并且对被分配的内存空间按字节清零

堆内存分配函数:realloc(void *,size_t)

函数原型:void* realloc(void *,size_t);

从某一个地址开始分配size_t个内存空间

5、栈区:申请内存的模式采用先进后出,后进先出。

栈底的地址高,栈顶的地址低。

先入地址高,后入地址低。

栈区的内存空间在8M左右

栈区分配内存的测试

char str[8383240] = {0};

二、全局变量,局部变量

一个大括号看作一个作用域;在不同作用域内,变量可以重命名。

局部变量作用域其优先级别比全局变量优先级别更高

全局变量作用域更大,相对于局部变量。

·DAY_9 C语言函数指针

一、函数指针的定义:指向函数的指针

整型指针的定义:指针类型 指针变量

指针的重定向

函数名是一个地址

定义一个指针指向函数

定义一个函数指针(类型:具有两个整型参数(一个为整型数组,一个为整型))无返回值的函数指针)

void (*p)(int *,int) = NULL;

指针p是一个整型,函数sum是具有两个整型参数,一个整型返回值的函数,因此类型不匹配

int *p = NULL;p = sum;//错误

int (*p)(int ,int) = NULL;

p = sum;

通过指针名调用函数

int a = p(10,20);

二、取别名(为函数指针取别名)

为具有两个整型参数,一个整型返回值的函数指针类型取别名

在函数指针最前面加上typedef,去掉=以及右边的东西,此时指针名就成为了类型名

typedef int (*P)(int,int);

//通过别名定义函数指针

P p = NULL;

//将指针p指向sum函数

p = sum;

//通过指针调用

int a = p(10,10);

三、函数回调

第一步:用一个函数实现功能a;

第二部:将需要封装的代码拿出来作为函数b,在a的实现里进行调用;

第三步:定义一个函数指针类型和b一样,作为a的参数,将a实现体中b函数名换成指针名。

函数指针作为函数参数,函数调用时传入函数地址.