目录
1.数组的概念和定义
dataType arrayName[length];//定义
eg:int a[4];
使用数组元素:
arrayName[index] = XX;//赋值
int a[4] = {20, 345, 700, 22};//定义加赋值
int a[] = {1, 2, 3, 4, 5};//第三种定义加赋值
如果只初始化部分数组元素,那么剩余的数组元素也会自动初始化为“零”值,所以我们只需要将 str 的第 0 个元素赋值为 0,剩下的元素就都是 0 了。
2.二维数组:2个下标
dataType arrayName[length1][length2];
二维数组在概念上是二维的,但在内存中是连续存放的;换句话说,二维数组的各个元素是相互挨着的,彼此之间没有缝隙。那么,如何在线性内存中存放二维数组呢?有两种方式:
一种是按行排列, 即放完一行之后再放入第二行;在C语言中,二维数组是按行排列的。也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;
二维数组的初始化可以按行分段赋值,也可按行连续赋值。
例如,对于数组 a[5][3],按行分段赋值应该写作:
int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
按行连续赋值应该写作:
int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};
这两种赋初值的结果是完全相同的。
二维数组a[3][4]
可分解为三个一维数组,它们的数组名分别为 a[0]、a[1]、a[2]
3。字符数组
char str[30] = {"c.biancheng.net"};
char str[] = {"c.biancheng.net"};
在C语言中,字符串总是以'\0'
作为结尾,所以'\0'
也被称为字符串结束标志,或者字符串结束符。
逐个字符地给数组赋值并不会自动添加'\0'
在很多编译器下,局部变量的初始值是随机的,是垃圾值,而不是我们通常认为的“零”值。局部数组(在函数内部定义的数组,本例中的 str 数组就是在 main() 函数内部定义的)也有这个问题,很多编译器并不会把局部数组的内存都初始化为“零”值,而是放任不管,爱是什么就是什么,所以它们的值也是没有意义的,也是垃圾值。
在函数内部定义的变量、数组、结构体、共用体等都称为局部数据。在很多编译器下,局部数据的初始值都是随机的、无意义的,而不是我们通常认为的“零”值。这一点非常重要,大家一定要谨记,否则后面会遇到很多奇葩的错误。
4.字符串长度
在C语言中,我们使用string.h
头文件中的 strlen() 函数来求字符串的长度,它的用法为:
length strlen(strname);
strname 是字符串的名字,或者字符数组的名字;length 是使用 strlen() 后得到的字符串长度,是一个整数。
5.字符串输入输出:
就目前学到的知识而言,int、char、float 等类型的变量用于 scanf() 时都要在前面添加&
,而数组或者字符串用于 scanf() 时不用添加&
,它们本身就会转换为地址。读者一定要谨记这一点。
6.字符串处理函数:
用于输入输出的字符串函数,例如printf
、puts
、scanf
、gets
等,使用时要包含头文件stdio.h
,而使用其它字符串函数要包含头文件string.h
。
字符串连接函数 strcat()
strcat 是 string catenate 的缩写,意思是把两个字符串拼接在一起,语法格式为:
strcat(arrayName1, arrayName2);
strcat() 将把 arrayName2 连接到 arrayName1 后面,并删除原来 arrayName1 最后的结束标志'\0'
。这意味着,arrayName1 必须足够长,要能够同时容纳 arrayName1 和 arrayName2,否则会越界(超出范围)。
字符串复制函数 strcpy()
strcpy 是 string copy 的缩写,意思是字符串复制,也即将字符串从一个地方复制到另外一个地方,语法格式为:
strcpy(arrayName1, arrayName2);
strcpy() 会把 arrayName2 中的字符串拷贝到 arrayName1 中,字符串结束标志'\0'
也一同拷贝。str1 中原来的内容就被覆盖了。
字符串比较函数 strcmp()
strcmp 是 string compare 的缩写,意思是字符串比较,语法格式为:
strcmp(arrayName1, arrayName2);
arrayName1 和 arrayName2 是需要比较的两个字符串。
字符本身没有大小之分,strcmp() 以各个字符对应的 ASCII 码值进行比较。strcmp() 从两个字符串的第 0 个字符开始比较,如果它们相等,就继续比较下一个字符,直到遇见不同的字符,或者到字符串的末尾。
返回值:若 arrayName1 和 arrayName2 相同,则返回0;若 arrayName1 大于 arrayName2,则返回大于 0 的值;若 arrayName1 小于 arrayName2,则返回小于0 的值。
7.对字符串排序
冒泡排序、归并排序、选择排序、插入排序、快速排序等,其中最经典最需要掌握的是「冒泡排序」。
8.查找和排序
关于查找和排序
学完了数组,有两项内容大家可以深入研究了,分别是查找(Search)和排序(Sort),它们在实际开发中都经常使用,比如:
给你 10 个打乱顺序的整数,要能够按照从小到大或者从大到小的顺序输出;
给定一个字符串 str1,以及一个子串 str2,要能够判断 str2 是否在 str1 中。
9.热身bug1
#include<stdio.h>
int main(){
char str1[] = {'a','b','c','d'};// {'a','b','c','d','\0'};
char str2[] = {"efgh"};
printf("%s\n",str1);
printf("%s\n",str2);
}
//输出结果:
abcdefgh
efgh
如果换成注释后的:
abce
efgh
原因分析:printf 遇到\0才结束,还有就是 局部变量是乱入,只有初始时候才不会乱入。
10.热身字符串包含判断
#include<stdio.h>
2 #include<string.h>
3 int main(){
4 char str1[] = {"thijdkhjdshjhdjskdhsdsjdhsdisisissismytestpro"};
5 char str2[] = {"is"};
6 int yes = 0;
7 for(int i=0;i<(strlen(str1)-strlen(str2));i++){
8 if (str1[i]==str2[0]){
9 for(int j=0;j<strlen(str2);j++){
10 if(str1[i+j]==str2[j]){
11 yes = 1;
12 }else{
13 yes=0;
14 }
15 }
16 }
17 }
18
19 printf("str2 in str1 ? %d\n",yes);
20
21 }
~