目录
数组
一维数组
一组相同类型的数据的集合,并且是有序的
b一维数组的创建
#include<stdio.h> int main() { int arr1[8];//定义数组 return 0; }
创建数组的大小只能是一个常量,不能是变量,但是C99的语法可以,但是VS不行
数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数
组的概念。
一维数组的初始化
对于整形数组未初始化的,系统自动将之初始化为0,字符型数组,则是‘\0',如果是指针型数组,则初始化为NULL。
#include<stdio.h> int main() { int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };//完全初始化 int arr3[10] = { 1,2,3,4,5 };//不完全初始化,为初始化的数据是0 int arr3[] = { 1,2,3,4,5 };//这个数组的大小由括号里的内容决定,长度是5 char ch[5] = { 'b','i','t' };//这个数组ch,不完全初始化,没有初始化的数据是结束符'\0' char ch3[5] = "bit"; // b i t \0 0 char ch4[] = "bit"; // b i t \0 char ch5[]={'b','i','t'};// b i t return 0; }
对于输出arr1,输出的是abc,因为字符串的输出是遇到'\0'结束,arr1的数组长度是3,在C语言中字符串是作为字符数组来处理的,字符串的有效长度而不是字符数组的长度,在程序中,往往是测'\0'的位置来判断字符串是否结束,而不是根据数组的长度来决定字符串的长度,所以一般数组长度应该大于字符串的长度
对于输出arr2,输出的是abc和一段随机的乱码,因为这个数组没有\0,所以不知道什么时候结束 ,arr2的长度是3,但是字符串长度不确定的
对于字符数组输入来说,空格符是作为输入字符串之间的分隔符,所以在输入时,如果将一个字符串输入到一个字符数组中,用scanf输入,若打了一个空格符,那么就会表示这个字符数组输入结束,系统并自动在后面加一个'\n'
一维数组的使用
对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。
我们来看代码:
#include<stdio.h> #include<string.h> int main() { int a[10] = {0};//把数组a的10个元素都变成0 for (int i = 0; i < 10; i++) { printf("%d\n", a[i]); } //输出10个0 a[4]=5; for (int i = 0; i < 10; i++) { printf("%d\n", a[i]); } //0 0 0 0 5 0 0 0 0 0 //计算数组的元素个数 int sz = sizeof(a) / sizeof(a[0]);//10 return 0; }
数组的下标是从0开始计数
一维数组在内存中的存储
#include<stdio.h> #include<string.h> int main() { int a[10] = {0}; int i = 0; printf("%p\n", 0X12);//00000012按地址格式打印,会自动补齐空白位 //在32位计算机中,为32个二进制位,所以有8个16进制位 printf("%x\n", 0x12);//12 按16进制打印 for (int i = 0; i < 10; i++) { printf("&a[%d]=%p\n",i, &a[i]); } /* & a[0] = 008FF788 & a[1] = 008FF78C & a[2] = 008FF790 & a[3] = 008FF794 & a[4] = 008FF798 & a[5] = 008FF79C & a[6] = 008FF7A0 & a[7] = 008FF7A4 & a[8] = 008FF7A8 & a[9] = 008FF7AC*/ return 0; }
一维数组在内存中是连续存放的
随着下标的的增长,地址是由低到高的变化的
#include<stdio.h> #include<string.h> int main() { int a1[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = a1;//数组名是数组元素的首元素的地址 for (int i = 0; i < 10; i++) { printf("%d\n", *p); p++; } //输出的是1 2 3 4 5 6 7 8 9 10 return 0; }
二维数组
二维数组的创建
#include<stdio.h> #include<string.h> int main() { int s[3][4]; char c[3][4]; return 0; }
二维数组的初始化
初始化就是创建的过程中也赋值
#include<stdio.h> #include<string.h> int main() { int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};//完全初始化 int s1[3][4] = { 1,2,3,4,5,6,7 };//不完全初始化,后面默认补0 int s2[3][4] = { {1,2},{3,4},{5,6} }; int s2[][4] = { {1,2},{3,4},{5,6} };//二维数组行数可以省略,列不能省略 return 0; }
二维数组的使用
二维数组行号和列号都是从0开始
#include<stdio.h> #include<string.h> int main() { int s3[][4] = { {1,2},{3,4},{5,6} }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) printf("%d ", s3[i][j]); printf("\n"); } return 0; }
二维数组在内存中的储存
#include <stdio.h> int main() { int arr[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int i = 0; for(i=0; i<3; i++) { int j = 0; for(j=0; j<4; j++) { printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]); } } int* p = &s[0][0]; for (int i = 0; i <12; i++) { printf("%d\n", *p); p++; } //输出 1 2 3 4 5 6 7 8 9 10 11 12 return 0; }
通过结果可知二维数组在内存中也是连续储存的
数组越界
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的,
所以程序员写代码时,最好自己做越界的检查。
二维数组的行和列也可能存在越界。
数组作为函数参数
往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法 思想)函数
数组名是什么
#include <stdio.h> int main() { int arr[10] = {1,2,3,4,5}; printf("%p\n", arr); printf("%p\n", &arr[0]); //输出结果 输出的结果是一样的 printf("%d\n", *arr); return 0; }
#include<stdio.h> #include<string.h> int main() { int ss[10]; printf("%p\n", ss); printf("%p\n", ss+ 1); //这两个相差4 printf("%p\n", &ss); printf("%p\n", &ss+ 1); //这两个相差40 return 0; }