数组
数组:相同的数据类型成员组成的数据。
如:整型数组,浮点型数组。
数组的形式为:
类型修饰符数组名[常量表达式] = { 1,2,3……..};
说明:数组在定义的时候,[ ]里必须用常量表达式,不能用变量表达式来代替。但是数组在使用的时候,[ ]中可以用变量来代替。
数组和循环是一对好基友。
数组的几个注意的点:
1、只有定义时,[ ]内为常量表达式。不能放变量。
// int n =3; // int arr1[n] = {10,20,30};//报错 |
2、[ ]可以放算术式。
// int arr2[1+2] = {10,20,30}; |
3、初始化时可以放多余空间的元素(但是这是不对的)
// int arr3[3] = {10,20,30,40}; |
4、定义时,可以不给出常量表达式。(数组可以通过元素个数推算空间)。给出多少个元素,会自动给你分配多少空间
// int arr4[] = {10,20,30}; |
5、前三个空间值分别为10,20,30,后面的7个空间全部清0,为0。
// int arr5[10] = {10,20,30}; |
6、数组初始化
// int arr6[3] = {0}; // //错误的 // int arr7[] = {0}; |
一些例子:
//练习
// float arr_f[3] = {3.1,5.2,7.9};
//使用数组 // int arr8[3] = {10,20,30};
// printf("%d",arr8[0]); // printf("%d",arr8[1]); // printf("%d",arr8[2]); |
数组取值:
//使用数组可以用下标取值
//下标可以使用变量
//数组可以使用循环取出所有值
// for (int i = 0; i < 3; i ++) { // printf("%d \n",arr8[i]); // } |
越界
1、存储的时候越界:
//第一种,存储的时候越界 // int arr9[3] = {10,20,30,40};//此时,40已经被写入内存,但是取值的时候,40所在的内存空间已经被修改,所以取值的时候,很难取到40 // // for (int i = 0; i < 4; i ++) {//循环4次,打印10,20,30,0(不同的计算机打印出来的值不同) // // printf("%d\n",arr9[i]); // } // |
2、使用的时候越界
//第二种,使用的时候越界
// int arr10[3] = {10,20,30}; // // arr10[0] = 50;//自己定义的数组,可以随便改。 // // printf("%d",arr10[0]);//打印50 // // // arr10[3] = 50;//可以访问之后的任意空间,本数组的第4个内存空间位置,被改动。 // // printf("%d",arr10[3]);//打印50 |
C语言可以通过我们定义的数组,操作本数组之后的所有内存空间,那些空间不属于这个数组,谁都可以去用。因此可以在上面进行读写。这样就会使得程序不安全。
数组越界是一件很危险的事情,我们无法把控,因此我们在操作程序是,尽可能的避免越界产生。
数组是一个整体,不能直接参与运算,只能对各个元素进行处理。
一些代码:
//练习
//1、定义一个具有20个元素的整型数组,30~70间的随机数,求和。
// //定义数组,并清零,初始化。 // int array[20] = {0}; // //求和变量 // int sum = 0; // printf("20个随机数为:\n"); // //产生20个随机数 // for (int i = 0; i < 20; i++) { // unsigned num = arc4random() % (70-30+1)+30; // printf("%d\t",num); // array[i] = num; // //不要在这个地方求和,一个for一个功能。增加代码的重用性。 //// sum = sum + array[i]; // }
// //求和 // for (int i = 0; i < 20 ; i ++) { // sum += array[i]; // } // // // printf("\n\n20个数的和 sum = %d",sum);
//2、复制数组。 // int array1[5] = {10,20,30,40,50}; // int array2[5] = {0}; // for (int i = 0; i < 5; i ++) { // array2[i] = array1[i]; // printf("%d\t",array2[i]); // }
|
排序
冒泡排序
从第一个数开始,用第一个数分别与后面的数进行比较,若是大于后面的数,则将该数放在后面。然后再用第二个数跟后面的数比较,若大于后面的数,则将该数放在后面,依次类推,一直到最后一个数比较完毕为止。此时,排序已经完成。
//数组排序
// //冒泡排序(只适合小范围的数据排序)(20遍) // int sort_arr[5] = {5,4,3,2,1}; // //外层循环,控制排序趟数,趟数为:数组元素个数-1 // for (int i = 0; i < (5-1)/*5-1,表示数组有n个数比较,只比较n-1趟*/; i ++) { // //内层for循环,控制比较次数 // for (int j = 0; j < 5 - (i+1)/*本来应该是5-i,但是i是从0开始的,我们要得是从1开始,因此要5-(i+1)。此处的意思是每一趟,比较多少次。*/; j ++) { // //判断,并且交换。 // if (sort_arr[j] > sort_arr[j+1]) { // //交换,不使用第三个变量交换,用亦或 ^的方法最好。 // sort_arr[j] = sort_arr[j] ^ sort_arr[j+1]; // sort_arr[j+1] = sort_arr[j] ^ sort_arr[j+1]; // sort_arr[j] = sort_arr[j] ^ sort_arr[j+1]; // } // } // } // //打印 // printf("冒泡排序后:"); // for (int i = 0; i < 5; i ++) { // printf("%d\t",sort_arr[i]); // }
//练习 // //随机产生10个[20,40]间的数,排序 // // int array[10] = {0}; // printf("排序前的10个数为:\n"); // //取随机数 // for (int i = 0; i < 10 ; i ++) { // unsigned num = arc4random() % 21+20; // array[i] = num; // printf("%d\t",array[i]); // } // // //排序开始 // //外层for循环,控制比较多少趟。 // for (int i = 0; i < 10-1; i ++) { // //内层for循环,控制比较多少次 // for (int j = 0; j < 10 -(i+1); j ++) { // //冒泡排序 // if (array[j] > array[j+1]) { // //亦或,用来交换两个变量的值。 // array[j] = array[j] ^ array[j+1]; // array[j+1] = array[j] ^ array[j+1]; // array[j] = array[j] ^ array[j+1]; // } // } // } // printf("\n排序后的10个数为:\n"); // for (int i = 0 ; i < 10 ; i ++) { // printf("%d\t",array[i]); // }
|
字符数组
第一种定义:
char array[5] = {'h','e','l','l','o'}; |
第二种定义:
char array1[6] = "hello"; |
第二种定义在定义的时候,自动添加一个'\0'。这个\0有着特定的意义,在接下来输出这个数组时,将会用%s来作为占位符,当%s在输出数组时,遇到了’\0’这个特定意义的“结束标识符”时,就会终止打印,停止输出。
此时,数组的实际长度为:字符数组元素个数+1,要留出'\0'的位置。
// //%s占位符 //// for (int i = 0; i <5 ; i++) { //// printf("%c",array[i]); //// } // printf("%s",array);//打印:hello |
一些情况:
// //自动推算出有6个位置 // char array2[] = "hello"; // // // //前面补满,后面补0 // char array3[10] = "hello";
//存储打印中文 // char array3[20] = "蓝欧�� |