第七章-数组
- 定义:用来存储一组数据
- 特点:只能存放一种类型的数据,比如int类型的数组、float类型的数组
- 数组的定义:
- 格式: 元素类型 数组名[元素个数];
- 比如:int ages[3];
- 数组常见的初始化:
- int ages[5] = {19, 19, 20, 21, 25};
- int a[] = {11, 7, 6};
- int b[10] = {1,2};
- 注意:对于指定数组长度,仅仅初始化前几个元素的情况,而其他未被初始化的元素,整型/浮点型系统都会默认为0,字符型数组则为
\0
,指针型数组,则为NULL
,即空指针 -
错误写法:
// 错误写法(不知道给数组分配多少内存) // int ages[]; // 只能在定义数组的同时进行初始化 int ages[5]; ages = {10, 11, 12, 14};
-
计算数组的长度
// 计算数组元素的个数 int ages[] = {10, 11, 12, 78}; int count = sizeof(ages)/sizeof(int);
- 数组的存储
- 存储空间的划分: 内存的分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的
- 定义两个变量:
char c = ‘A’; ```
- 定义一个字符数组
char cs[5]= {'a', 'A', 'D', 'e', 'f'};

- 因此:
- 变量的地址 = 最低字节的地址
- 数组的地址= 首元素的地址 = 数组名
- 数组和函数
- 数组作为函数参数,可以省略元素个数
-
数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组
void change(int array[]) { int s = sizeof(array); //永远等于8,因为:int array[] <=> int *array,指针占8个字节,因此要拿到数组的个数,只能在传一个参数记录 printf("%d\n", s); //数组地址==数组首元素地址 //printf("array==%p\n", array); array[0] = 100; } void change2(int n) { n = 100; } int main() { int ages[6] = {10, 11, 10, 11, 10, 11}; //printf("ages==%p\n", ages); //地址的传递(地址作为参数)ages[0]变化 change(ages); //值传递(基本数据类型作为参数) ages[0]不变 //change2(ages[0]); printf("%d\n", ages[0]); return 0; }
- 数组做函数参数的退化问题,退化为一个指针
- 结论: 把数组的内存首地址和数组的有效长度传给被调函数
- 实参a和形参a的数据类型本质不一样
- 形参中的数组,编译器会把它当成指针处理; c语言的特色。
- 形参写在参数()括号内,跟写在{}函数体中,是一样的效果,只不过是具有对外的属性而已。
//数组作为函数参数的问题。 void sortArray(int a[7], int num) //等价 //void sortArray(int a[], int num) //等价 //void sortArray(int *a, int num) //等价 { int i , j , tmp ; int num2 = 0; //形参中的a,只是一个指针变量,指向实参数组的首地址 num2 = sizeof(a)/sizeof(a[0]); printf("num:%d \n", num2); // 实参a和形参a的数据类型本质不一样,实参中的a是数组,形参只是指针 //形参中的数组,编译器会把它当成指针处理; c语言的特色。 for(i=0; i<num; i++) { for (j=i+1; j<num; j++) //ƒ⁄≤„—≠ª∑: a[i] ∫Õ a[j]±»Ωœ { if (a[i] > a[j]) { tmp = a[i]; a[i]= a[j]; a[j] = tmp; } } } } // 数组做函数参数的退回问题,退回为一个指针, //1 结论: 把数组的内存首地址和数组的有效长度传给被调函数 //2 实参a和形参a的数据类型本质不一样 //形参中的数组,编译器会把它当成指针处理; c语言的特色。 //3 形参写在参数()括号内,跟写在{}函数体中,是一样的效果,只不过是具有对外的属性而已。 void main22() { int i = 0,j = 0; int tmp = 0; int num = 0; int a[] = {33,654,4,455,6,33,4,3333}; num = 7; //实参中的a代表数组 num = sizeof(a)/sizeof(a[0]); printf("num:%d \n", num); sortArray(a, num); }
-
冒泡排序法
void main01() { int i = 0,j = 0; int tmp = 0; int a[] = {33,654,4,455,6,33,4}; //冒泡排序 //外层循环,当i=0的时候,让j从1到n进行变化 //外层循环,当i=1的时候,让j从2到n进行变化 //... //结论:让一个变量不变,让另外一个变量进行变化;下一轮 依次进行。 for(i=0; i<7; i++) { for (j=i+1; j<7; j++) //内层循环,a[i] 和 a[i]比较 { if (a[i] > a[j]) { tmp = a[i]; a[i]= a[j]; a[j] = tmp; } } } system("pause"); }
字符串
- 字符串是由多个字符组成的:char name[10] = “jack”;
- C语言中并没有专门用一个类型表示字符串,而是用字符数组表示字符串
-
字符串就是字符数组,字符数组不一定是字符串
#include <stdio.h> int main() { char name[] = "itcast"; name[3] = 'H'; int size = sizeof(name); //打印字符串占用的字节长度7 printf("%d\n", size); //打印字符串 printf("我在%s上课\n", name); return 0; } // 字符串的一个初始化 void test2() { // 都是字符串 char name[8] = "it"; char name2[8] = {'i', 't', '\0'}; // \0的ASCII码值是0(相当于\0) char name3[8] = {'i', 't', 0}; //元素不够,直接补零(相当于\0) char name4[8] = {'i', 't'}; // 不算是一个字符串(只能说是一个字符数组) char name5[] = {'i', 't'}; } void test() { //字符串就是结尾带\0的字符数组,只是展示方式不同 // "jack" == {'j','a','c','k','\0'} char name[10] = "jack888\n"; //打印字符串,把数组传入,仅仅是个警告(printf()中只放字符串常量) printf(name); //没有警告 printf("%s",name); }
-
注意事项:
int main() { char name[] = "itc\0ast"; char name2[] = {'o', 'k'}; //打印结果:okitc printf("%s\n", name2); //打印结果:kitc printf("%s\n", &name2[1]); return 0; } 分析: \0的作用:字符串结束的标记 内存分配由大到小,因此先分配name字符串,然后在分配name2字符数组,因此name2内存地址比较小 %s从当前地址开始输出字符,地址不断增加,知道遇到/0结束 因此会打印"okitc" 若果把name与name2换位置就回报错了,会一直找不到/0
- strlen函数:计算字符串长度
- 计算的是字符数,并不是字数。一个汉字算作3个字符
- 计算的字符不包括\0
- 从某个地址开始数字符的个数,直到遇到\0为止
- strlen函数声明在string.h文件中
char name[] = "itcast"; char name2[] = {'0','6'}; int size = strlen(name2); //打印结果8 printf("%d\n", size);