c语言第二周学习总结

本文详细介绍了C语言中的数组,包括概念、定义、初始化、访问以及特殊类型如字符数组和二维数组。指针部分讲解了指针的概念、定义、操作以及与一维和二维数组的关系。还讨论了函数的使用和自定义函数的声明、定义及调用。此外,文章提到了字符串处理函数如strlen、strcpy等,并简要介绍了函数参数传递中的值传递和地址传递。

day6

假设我们要定义1000个int类型的变量,通过上周的学习挨个去定义无疑是没有效率的。

使用数组去进行1000个int类型的变量是非常快速的;//int str【1000】,其中有1000个元素,每一个元素类型都是int类型。str【0】----str【999】;

1、数组概念

一组数据类型相同的元素的集合

特点:1、数据类型相同2、地址连续。通过“%p”打印地址

2、定义数组

存储类型 数据类型 变量名;

int a;

存储类型:auto、static、extern、register

存储类型 数据类型 数组名【元素的个数】;

int arr【5】;

//分配了一片内存空间,该内存空间存放5个int类型的元素,

数据类型:数组中元素的数据类型

数组所占的内存空间 = sizeof (数据类型)*元素的个数

//注意:1、int【5】和int【6】数据类型不相同。

2、数组的数据类型:去掉变量名,剩下的就是数据类型

数组名:1、数组首元素的地址2、整个数组

元素的个数:必须为一个确定的值(分配的内存大小是固定的)

3、初始化

3.1部分初始化

int arr【5】={1,2,3};

arr【0】=1 ,arr【1】=2,arr【2】= 3 ,arr【3】,arr【4】???

//部分初始化时:没有初始化的部分,其值为0,利用此特性,可以给数组清零;

如何给数组清理?

int arr【100】={0};

3.2全部初始化

int arr【5】={1,2,3,4,5};

int【 】= {1,2,3};//此时元素的个数可以省略,编译器它会自动计算元素的个数(只有在全局初始化时,才可以省略元素的个数)

总结:

  1. 在函数体内,定义一个数组(相当于在函数体内,定义一个变量),其值为随机值

  1. 在函数体外,定义一个数组(相当于在函数体外,定义一个变量),其值为0

  1. 在函数体内,用static修饰的数组(static修饰是一个局部变量),其值为0

4、访问

数组名【下标】;

下标从0开始;

案例:实现对数组的输入和输出

案例:判断对错

5、冒泡排序

如上图所示,冒泡排序:从左往右依次比较,前一个数比后一个数大位置交换,反之,不变!

总结:5个数交换4趟,每一趟比较4-1次。N个数交换N-1趟,比较N-1-J次。i为趟数j为次数。

定义一个中间变量:实现交换,每一趟比较,都会得到一个最大的数!

案例:

6、字符数组

整型数组:存储一堆整型数

存储类型 数据类型 数组名【元素的个数】;

int a【10】;

//分配了10个4字节大小的空间;里面保存了10个int类型的元素

字符数组:存储一堆字符

存储类型 数据类型 数组名【元素的个数】;

char str【10】

数据类型:元素的数据类型

字符数组的数据类型:char【10】;

//分配了10个1字节大小的空间,里面保存10个char类型的元素

字符串在c语言中如何保存?

int :10,20,30,

char:‘a’,‘b’(保存字符)

float:3.14;

如何保存字符串?

“hello”有什么构成 ‘h’‘e’‘l’ 'l' 'o' '\0'

字符串用字符数组进行保存;

字符数组的本质:就是字符串

char str【6】={h’‘e’‘l’ 'l' 'o' '\0'};

char str【6】=“hello”;

字符串数组清零:

char str【10】={0};

char btr【10】={'\0'};

6.1字符串的输出函数

怎样去输出字符串:“%s”

puts(数组名);

功能:将数组中的内容打印到终端,并且自动换行;

注意:遇到'\0'结束

6.2字符串的输入函数

gets(数组名);

功能:将键盘接收到的字符串存放到数组中,并在末尾自动添加'\0'

注意:gets不会进行越界检查,所以输入的时候不要越界

7、总结

7.1gets和scanf的区别

1、scanf以空格、回车、tab作为输入结束的标志,gets以回车作为结束符

2、缓冲区:

gets:当字符串输入完毕之后,会清空缓冲区里面的东西

scanf:当字符串输入完毕之后,会在缓冲区内遗留空格、回车、tab键

3、gets先检查缓冲区内有没有东西,如果有,直接拿来用,没有的话,采取键入的方式

scanf:键入的方式

7.2puts和printf的区别

puts会自动添加换行,而printf不会。

day7

1、字符串的处理函数

strlen、strcpy、strcat、strcmp

头文件:#include <string.h>

1.1 求字符串的长度

strlen(数组名);

功能:求字符串的实际长度

返回值:求得的字符串的实际长度,不包含'\0'

strlen和sizeof的区别:

  1. strlen计算的是字符串的实际长度(不包含‘\0’),sizeof计算的是整个空间的大小

  1. strlen是一个函数,sizeof是一个运算符

案例:不使用strlen求字符串的实际长度

1.2字符串的拷贝函数

strcpy(数组1,数组2/字符串2);

功能:将数组2中的内容拷贝到数组1中,包含‘\0’,相当于完全拷贝

注意:数组1的长度要大于数组2

strncpy(数组1,数组2/字符串,n);

功能:将数组2的前n个字符拷贝到数组1中

案例:不适用strcpy函数实现字符串的拷贝!

1.3 字符串的连接函数

strcat(数组1,数组2/字符串);

功能:将数组2/字符串中的内容连接到数组1中,数组1中的‘\0’会被覆盖

注意:数组1的空间要足够大

strncat(数组1,数组2/字符串,n);

功能:将数组2/字符串的前n个字符连接到数组1后

案例:不适用strcat,实现字符串的链接(先画图)

1.4 字符串的比较函数

strcmp(数组1/字符串1,数组2/字符串2)

功能:比较字符串1和字符串2的大小

返回值:

大于0:字符串1 > 字符换2

等于0:字符串1 == 字符串2

小于0:字符串1 < 字符串2

比较规则:

从左往右,依次对字符中的ascii码值进行比较,直到遇到不同的ascii码或者遇到‘\0’结束

2、二维数组

  1. 概念

数组:一组数据类型相同的元素的集合

整型数组:一组int类型的数集合在一起

字符数组:一组char类型的字符集合在一起

二维数组:(数组的数组):一组(数组类型的)元素集合在一起

本质:概念:元素为一维数组的一维数组

特点:1、数组类型相同2、地址连续

2.定义

存储类型 数据类型 数组名【元素的个数】;

心态 a【3】;

数据类型:数组中元素的数据类型

数组的数组类型:int【3】(去掉数组名)

2.1定义二维数组

存储类型 数据类型 数组名【行数】【列数】;

int arr【行数】【列数】:

行数:一维数组的个数

列数:一维数组中元素的个数

数据类型:最里面的元素的数据类型

实际的元素的个数 = 行数*列数

内存空间:sizeof(最里面的元素的数据类型)*实际的元素的个数

3、初始化

3.1 部分初始化

int a【2】【3】={1,2};

int a【2】【3】={{1,2,3},{1}};

3.2全部初始化

int a【2】【3】={1,2,3,4,,5,6};

int a【2】【3】={{1,2,3},{4,5,6}};

int a【行数】【列数】;

思考:行数和列数是否可以省略?

  1. 行数是否可以省略?

int【】【3】={1,2,3,4};

行数:有几个一维数组,此时计算机可以自动计算出行数

  1. 列数是否可以省略?

int a【2】【】={1,2,3,4};

列数:一维数组中元素的个数?

有两个一维数组,但是每一个一维数组中不知道存放几个元素

注意:二维数组在进行全部初始化时,行数可以省略,列数不可以省略!!

4、访问

数组名【下标】

案例:打印杨辉三角

5、二维字符数组

二维整型数组:

存储类型 数据类型 数组名【行数】【列数】;

行数:一维整型数组的个数

列数:每一个一维整型数组中元素的个数

二维整型数组;

int a【2】【3】;

//定义了一个二维数组,该数组中有两个一维数组,每一个一维数组中有3个int类型的元素

二维字符数组:

存储类型 数据类型 数组名【行数】【列数】;

行数:(一维字符数组的个数)字符串的个数

列数:(一维字符数组中字符的个数)每一个字符串最多能够存几个字符

定义一个二维字符数组:

存储类型 数据类型 数组名【行数】【列数】;

char str【5】【20】;

//相当于定义了一个二维字符数组,该数组中有5个字符串,每个字符串最多能够使用20字节的空间。

day8

1、函数

函数:具有一定功能的模块

2、为什么要有函数

  1. 让程序变得模块化

  1. 提高代码的复用率

3、函数的分类

3.1库函数

printf scanf strlen strcpy strcat strcmp

3.1.1引入头文件

#include <stdio.h>

#include <string.h>

3.1.2调用函数

strlen(str);

函数名(实际的参数);

注意:参数的类型,参数的个数,返回值

int length;

length = strlen(str);

3.2 自定义函数

3.2.1 函数定义

存储类型 数据类型 变量名;

存储类型 数据类型 函数名(形式参数列表)

{

函数体;

返回值;return ;

}

存储类型:auto、static、extern、register

数据类型:返回值的数据类型

函数名:满足标识符的命名规则,见名知意:(用函数名描述当前函数要实现的功能)

形式参数列表:实现这个功能,需要什么参数(1、需要几个参数2、每个参数都是什么类型,)需要调用这自己区传入

函数体:实现功能所需要的代码

返回值:如果没有返回值,不需要写return,数据类型:void。如果有返回值,有且只能有一个返回值。

3.2.2 调用函数

函数名(实参);

注意:

  1. 需要将实参的值传递给形参,实参的个数和数据类型必须和形参一致

  1. 实参可以是变量、常量、表达式,必须是一个确定的值

  1. 实参和形参是两块独立的空间

  1. 传参实际上是将实参的值拷贝给形参

  1. 形参是局部变量,在函数调用的时候被定义,函数调用完毕释放

3.2.3 调用时:

3.2.4 调用完毕:

3.2.5 函数的声明:

如果自定义的函数在main函数之后,需要加上函数的声明

声明:将函数的头赋值,然后粘贴在程序的上面,加上分号;

声明的作用:帮助编译器做检查

案例:封装函数实现+-*/

4、指针

4.1什么是指针

指针是一种数据类型,一种保存地址的数据类型

int a;//int:用来保存整型数的数据类型

float b;//float:用来保存小数的数据类型

char c;//char:用来保存字符的数据类型

指针 d;//指针:用来保存地址的数据类型

4.2 地址是什么

整型数:1,2,3,4

小数:2.3,5.234

字符:‘a’ ‘B’

地址:0x100 0x104

内存分配的时候,最小的单位:字节;每一个字节都有一个编号,我们把这个编号叫做地址;

地址:内存单元的编号

地址就是指针

指针就是地址

指针的本质:内存单元的编号

4.3 指针变量

int a = 10;

a:整型变量 10:整型常量

a++;

10++;

0x100

指针常量:

什么是指针变量:

int a;//a就是整型变量

char b;//b就是字符变量

float c;//c就是浮点型变量

指针 d;//d就是指针变量

4.4 定义指针

存储类型 数据类型 *变量名;

int *p;

//定义了一个指针,编译器分配内存空间来保存地址,这片空间的名字叫做p

数据类型:指针指向的数据类型(去掉变量名和一个*,剩下的就是指针指向的数据类型)

指针的数据类型:int *(去掉变量名,剩下的就是数据类型)

存储类型:4个

  1. 间接访问

  1. 简介修改

*和&互逆:

int *p;

&a:获取a的地址

p = &a;//p指向a

*p = *(&a) = a;//取a这片地址里面的值

4.5指向(赋值:改变指针变量中保存的地址)

//将一个变量的地址赋值给指针,相当于指针指向他

int a = 10;

a = 20;

赋值时:注意类型匹配

指针变量中只能保存:他指向的数据类型的地址

注意:在所有的32os中,所有的指针都占据4个字节

在所有的64os中,所有的指针都占据8字节

4.6 空指针

零号地址:没有指针的指针,(NULL)

零号地址:禁止操作

但是可以指向

操作指针;改变指针的指向(赋值(地址))

4.7 野指针

不知道其指向的指针

局部变量:没有初始化,随机值

局部指针:没有指向NULL,随机指向

避免野指针:先让他指向零号地址

思考:为什么要有指针?

函数:实现两个数的交换

参数1:int

参数2:int

是否需要返回值?

在主函数中输出交换后的结果!

值传递

地址传递

day9

1、二级指针

1.1概念

本质:指针的指针(保存一级指针的地址)

二级指针的内存空间:用来保存一级指针的地址

1.2定义

定义一级指针:

存储类型 数据类型 *变量名;

int *p;

数据类型:指针指向的数据类型(p中保存的是整型数的地址)

一级指针的数据类型:(去掉变量名)int*

定义一个二级指针

存储类型 数据类型 *变量名;

int* *pp;

二级指针指向的数据类型:(二级指针中保存的是谁的地址):int*

总结:

  1. 指针的数据类型:(去掉变量名)

int *p//int *

int **p;//int **

int ***p;//int***

  1. 指针指向的数据类型:(去掉变量名和一个*,剩下的就是)

int *p;//int

char *p;//char

int **p;//int *

char **p;//char *

int ***p;//int **

  1. 指针能够访问到的内存空间的大小,由指针指向的数据类型所占的内存空间大小决定

int *p;//能够访问到的内存空间的大小:4字节:int

char *pp;//能够访问到的内存空间的大小:1字节:char

int **p;//所能访问到的内存空间的大小:4字节:int *

char **pp;//所能访问到的内存空间的大小:4字节:char *

2、指针的算术运算

测试:指针+1;加多大,加到了哪里(指向的数据类型)

总结:

  1. p+n:p+n相当于指针向地址增大的方向移动了n个数据

(实际的变化:p+sizeof(指向的数据类型)*n)

  1. p-n:p-n相当于指针向地址减小的方向移动了n个数据

(实际的变化:p-sizeof(指向的数据类型)*n)

  1. p++:p向地址增大的方向移动了一个数据(移动sizeof(指向的数据类型)字节)

  1. p--:p向地址减小的方向移动了一个数据(移动sizeof(指向的数据类型)字节)

  1. p-q:(p和q的数据类型必须一致)这两个指针中相差的元素的个数

实际结果:(p-q)/sizeof(指向的数据类型)

注意:

  1. 指针的算术运算只有在操作连续的内存空间时,才有意义

  1. p是指针变量,可以++,--,(指针常量也满足上面的算数运算规则,但是不可以++,--)

(数组名:1、数组首元素的地址(指针常量))

3、指针和一维数组的关系

3.1 指针常量与一维数组的关系

数组名:

  1. 数组首元素的地址,指针常量,不可以++,--

  1. 整个数组

数组名:指针常量,不可以++,--

3.2指针变量与一维数组的关系

注意:

1、printf中有表达式时,为右结合

2、

通过指针和数组之间的关系:(对数组进行输入输出)

指针移动:清楚指针在使用时指向谁!!!

冒泡排序

1、指针指向不发生改变
2、指针指向发生改变

4、指针和二维数组的关系

总结:

  1. a、a【0】、&a【0】【0】、&a、&a【0】,他们的值都是一样的,但是意义不一样

a: int (*)【3】;此时a指向一维数组

  1. 为什么a不是int **

如果a时int **类型,那么a+1移动4字节,(int **类型指向的数据类型为int *)

但是我们发现a+1移动了12字节(一个一维数组),所以此时a不是int **类型

  1. a指向a【0】,a【0】指向a【0】【0】

day10

1、数组指针

本质:指针

指向数组的指针

1.1概念

指向数组的指针

1.2定义

存储类型 数据类型 (*变量名)【元素的个数】;

int (*p)【5】;

此时p先和*结合,此时p的本质时一个指针

数据类型:指针指向的数组中的元素的数据类型

p的数据类型:int (*)【5】;

p指向的数据类型:int【5】;

*和【】的优先级:【】的优先级高于*的优先级;

p先和【】还是*结合,决定它的本质是什么东西;

【】:代表数组

*:代表指针

数组名:

  1. 数组首元素的地址:int *(指针常量)

  1. 整个数组:【5】(变量)

1.3 数组指针和一维数组的关系

注意:数组指针一般不去操作一维数组,因为p+1,移动了一个数组,指向了数组底部(我们没有申请到的内存空间),因此,我们一般使用数组指针操作二位数组。

1.4数组指针和二维数组的关系

2、指针数组

本质:数组

数组中保存的都是指针类型

2.1概念

数组中存放的元素都是指针类型

2.2定义

定义了一个数组;

存储类型 数据类型 数组名【元素的个数】;

数据类型:元素的数据类型 int

定义一个指针数组:

存储的元素的数据类型:int *

定义一个存储 int *类型的元素的数组

存储类型 数据类型* 数组名【元素的个数】;

int* a【3】;

此时变量名先和【】结合,所以此时a时一个数组

2.3 指针数组和二维数组的关系

3、const

const 修饰变量:

只读

(不能直接去修改!)

const修饰指针:

int *p

左数右指(const关于*的位置)

*p就是数,p指向

const int *p;

int const *p;

int *const p;

const int *const p;

int const *const p;

4、main函数传参

  1. 参数的个数

  1. 保存传入的字符串

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值