1 二维数组
二维数组的定义,存储
- 〈存储类型〉〈数据类型〉〈数组名〉[〈常量表达式〉][〈常量表达式〉]。第一个为行号,第二个为列号
- 二维数组的初始化和遍历
- 二维数组声明时列数不可以省略,行数可以
- 在内存中按行序优先联系存放
- 初始化份行初始化,如a[2][2]={{1,4},{4,6}}
- char a[5][4],则a[2]表示的是数值第3行的首地址,不是数值
打印杨辉三角形
- 杨辉三角。分三步1打印一个完整正方形的全为1,2变成全是1的三角。3加入杨辉三角算法
- 找出二维数组中的最大值
2 字符数组和字符串
一维字符数组和字符串
- 字符数组是元素类型为字符类型的数组
- C语言中没有字符串类型,用字符数组处理字符串。以\0结束的字符数组也是字符串
- 初始化方式1.逐个字符赋值2.用字符串常量。
- 注意逐个赋值的如果最后没有\0≠字符串赋值的
- 如char a[]={`a`,`b`,`c`};和char b[6]={`a`,`b`,`c`};是不相等的,b是字符数组同时也是字符串
- 使用printf("%s")打印字符数值时,会一直按照地址打印到有\0为止
- 获取用户输入存在a数组里的字符个数=》strlen函数
二维字符数组和字符串
- 一维数组只能放一个字符串,再有多个字符串的时候要用二维数组存放
- 字符串逆序输出
3. 字符串处理上
- 关于字符串操作的函数都在头文件 string.h
字符串长度strlen函数
- 计算的是有效字符长度,不算\0
- 转意字符占一个字节长度
- srtlen格式:strlen(〈数组名〉)
字符串拷贝strcpy
- strcpy(字符串1,字符串2)。把字符串2付给字符串1
- 如果字符串1比字符串2小,只有字符串1大小内的内容是正常的
- 拷贝时会连‘\0’一起拷贝
字符串连接strcat
- strcat(字符串1,字符串2)。把字符串2接到字符串1后面,存到数组1中
- 注意。字符串数值1必须足够大。
- 两个合并的必须都是字符串,注意别用字符数组当字符串使用。函数会找两个\0拼到一起,字符数组没有\0
字符串比较函数strcmp
- 对两个字符串从左到右按个字符进行比较,直到出现\0或着比较出大小关系了,就停止。
- 返回值,字符串1<字符串2,返回负值。字符串1>字符串2,返回正值。等于返回0
- 如果误用了一个字符数组当字符串用,那么会一直比较到\0到
4. 字符串处理函数下
更安全细节的字符串操作函数
- strncpy(字符串1,字符串2,n位数),用字符串2的前n位开始去覆盖掉字符串1的前n位
- strncat(字符串1,字符串2,n)。把字符串2的前n位接到字符串1后面,存到数组1中
- strncmp(字符串1,字符串2,n)。比较前n个字符的大小
- strcasecmp(字符串1,字符串2,n)。忽略大小写比较字符串。
- strchr(p,c)。在字符串p中查找字符c。
- strstr(p,p1)。在p中查找字符串p1的内容
检查字符函数
- 头文件 ctype.h
- isalpha()检查是否为字母字符
- isupper()检查是否为大写字母字符
- islower()检查是否为小写字母字符
- isdigit()检查是否为数字
- tolower()转换成小写字母
- toupper()转换成大写字母
5. 指针的基本用法
- 指针定义:在C语言中,内存单元的地址称为指针,专门用来存放地址变量的称为指针变量。
- 指针的优点:1 使程序简洁,高效;2 有效的表达复杂的数据结构;3 动态分配内存;4得到多于一个的函数返回值
- px——指针变量,内容是地址量
- *px——指针所指向的对象,内容是数据
- &px——指针变量占用的存储区的地址,内容是地址量(常量)
- 指针占的字节与设备有关,32位系统为4个字节。64位系统占8个字节
6. 指针的运算
指针算数运算符表
-
不同数据类型的指针相加减没有意义
-
指针px+n表示实际位置的地址量是:px+sizeof(px的类型)*n
-
指针相减得到的不是两个地址的差值,而是两个指针间相隔数据的个数
-
指针与整数之间进行运算意义不大。但是可以和0比较是否相等来判断是否为空指针。
-
指针px++。向后移动了一位数据
指针关系运算符
- 两指针之间的关系运算表示它们指向的地址位置之间的关系。指向地址大的指针大于指向地址小的指针。
- 指针与一般整数变量之间的关系运算没有意义。但可以和零进行等于或不等于的关系运算,判断指针是否为空。
7. 指针与一维数组
- 一维数组名就是一维数组的指针(起始地址)
- 设指针变量p等于数值指针x。则数值p[i]等于*(p+i)等于*(x+i)等于x[i]。
- 区别:指针是地址变量,数组的指针(数组名)是地址常量。常量数据本身不能变化
8. 一级指针遍历二维数组
- 二维数组也是连续存储的,可以看成多个一维数组连起来的数组
- 用一维数组指针来遍历二维数组时,指针的类型和二维数组的类型是不一样的。直接让p=a,会有警告改成p=&a[0][0];
- 二维数组名代表数组起始地址,数组名+1是移动一行元素。因此二维数组名称为行地址。
- 行指针,存储行地址的指针变量叫做行指针。例如:int (*p)[3];
9. 字符指针与字符串
- 通常把char类型的指针叫做字符指针变量
- 当把字符串直接赋给变量时,这个字符串是个字符串常量。(常量的数据值不能修改)
- 放在静态存储区的数据 1 全局变量;2 static修饰的变量;3 字符串常量
- 修改字符串常量会报段错误
10. 指针数组
- 定义:指由若干个具有相同存储类型和数据类型的指针变量构成的数组(本质还是数组就是里面存的都是指针变量)
- int *p[n];这是指针数组。int (*p)[3];这是数组指针
- 用指针数组访问二维数组。其实就是用指针数组中每个指针指向二维数组每行的首地址。
- 指针数组名相当于一个什么样的指针。int *p[2];现在想要一个指针指向这个指针数组,则int * *q = p。
11. 多级指针、void指针与const
- 指向指针变量的指针称为多级指针
- 二级指针+1是移动了4个字节
- 多级指针也是一个指针也占4个字节
- 指针类型的转换x=*(int *)p;
- void指针用的时候根据需要可以强制类型转换成需要的类型
- const变量。const修饰后变量的值不能改变
- 使用const修饰的变量,如果指针想访问的话指针也要用const修饰
- int const 和const int意义完全相同
- const * int 表示指针所指向地址的值不能修改
- * const int 表示指针所指向的地址不能修改
- main函数的参数。argc输入字符串的个数,argv内存着输入的字符串
- volatile关键字是一个类型修饰符,用来防止编译器优化
12-13. 函数的基本用法及传参
- 定义:函数是完成一个特定功能的代码块,其程序代码独立,通常要求有返回值
- 函数传参
- 函数直接参数传递方式:1 全局变量;2 复制传递方式;3 地址传递方式
- 不同函数之间变量可以重名
- 形参是新开辟的存储空间,在函数里对形参的值改变不会影响实参的值
- 如果传参是指针且不需要改变在定义前加个const修饰。能告诉别人这个函数不改变内容
14 指针函数
- 定义:一个函数的返回值为地址量的函数
- 函数内的局部变量不能用来当做指针函数的返回值。可以用static修饰
- 指针函数的返回值。全局变量,static修饰的变量,字符串常量的地址,堆的地址
15. 递归函数和函数指针
- 递归函数是指一个函数的函数体中直接或者间接的调用函数本身
- 递归函数执行分为两个阶段,递归阶段,回归阶段(就是要有结束条件)
- 斐波那契数列:1,1,2,3,5,8,13…数列从第3项开始,每一项都等于前两项之和
- 函数指针
- 用来存放函数的地址的指针叫函数指针
- 〈数据类型〉 (*〈函数指针名称〉)(〈参数说明列表〉)
- 函数指针数组。〈数据类型〉 (*〈函数指针名称〉)[〈元素个数〉](〈参数说明列表〉)