基本概念:
逻辑: 一次性定义
多个
相同
类型
的变量,并把他们的内存统一分布在
一片连续的内存空间(顺序
存储)
。
语法:
1 类型 数组名 [ 元素个数 ] ;
2 int arr [10];
定义与初始化:
int arr [3] ; // 定义了一个数组名为 arr 元素个数为 3 ,并没有初始化,他的值为随机值
int arr1 [5] = {0} ;// 定义数组并初始化为0 , 不完整初始化,未初始化部分会被系统自动初始化为 0
int arr2 [5] = {1,2,3} ; // 不完整初始化, 前面三个元素的值分别为123,但是后面两个自动设置为 0
int arr3 [5] = {1,2,3,4,5} ; // 完全初始化
char c = 'a' ;
char arrch[6] = {'a','b','c','d' , '\0'}; // 有结束符因此为字符串数组
char arrch[4] = {'a','b','c','d' , '\0'}; // 无法存入结束符因此为字符数组
char arrch[6] = "abcd"; // 双引号的数据默认是字符串格式的因此带有结束符
char arrch[4] = "abcd"; // 无法存入结束符因此为字符数组
int arr4 [5] = {1,2,3,4,5,6,7,8} ; // 在当前的编译器中后面超出的6.7.8会被直接丢弃
int arr5 [ ] = {1,2,3,4,5,6,7,8} ; // 定义的时候可以省略数组的元素的个数不写,但是要求必须有初
int arr6 [ ] ; // [错误] 数组在定义的时候必须要确定他的大小
int arr7 [ 0 ] ; // 允许 数组的大小为 0 【零长数组】--> 放在结构体作为最后一个成员有用
注意:
数组在定义的时候必须确定他的大小长度(元素的个数)。可以
省略元素个数
不写,但是
必须
写初始化
, 如果
不想写初始化
那就
必须写数组元素个数
。
数组元素的引用:
数组的下标(偏移量)
概念: 数组的下标也称为某一个元素的偏移量。
解读:数组名字代表的是
该数组的入口地址
。后面的某一个元素就通过
偏移量
来访问,可以理解为是数组的第几个元素。偏移量从 0开始,因此数组的下标也是从0开始。 下标的最大值 应该为数组元素的个数 -1 。
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
arr [ 5 ] = 250 ; // 访问arr数组的第5个元素并把他的值改成 250
printf( "%d\n" , arr[5] );
练习:
尝试定义一个数组,并访问数组中的每一个元素(循环体)。
#include <stdio.h>
int main()
{
int arr[7]={1,2,3,4,5,6,7};
for(int i=0;i<7;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
注意:
数组的下标是从0 开始的, 因此最大的下标应该等于实际元素个数 -1 。
数组是C语言中唯一一个允许越绝访问的方式, 但是越界之后的值不可预测。
实例:
1、完全不初始化, 以下代码输出的数组的值为随机值
#include <stdio.h>
int main()
{
int arr[10];
for(int i=0;i<10;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
2、不完全初始化,以下代码输出的值前4个为初始化的值,后面则为0
#include <stdio.h>
int main()
{
int arr[8]={1,2,3,4};
for(int i=0;i<8;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
3、越界访问,以下代码中,数组的合法元素个数为 8 个 ,但是循环体中有13个需要输出, 那么超出部分则输出随机值
#include <stdio.h>
int main()
{
int arr[8]={1,2,3,4,5,6,7,8};
for(int i=0;i<13;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
4、数组越界初始化,以下代码中注意数组的大小设置为8 ,因此该数组理论上只能存入初始化语句中的前8个数据, 后面的会被编译器直接丢弃 , 因此输出超过数组范围的数据为随机值
#include <stdio.h>
int main()
{
int arr[8]={1,2,3,4,5,6,7,8,9,10,11,12,13};
for(int i=0;i<13;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
数组的尺寸:
数组的尺寸取决于
元素的个数
以及
数据的类型
。
如何计算数组的大小:
sizeof (数组名) ——————> 计算的是整个数组的大小 元素类型* 元素个数
sizeof(arr) ;
printf("sizeof(arr3):%ld\n" , sizeof(arr3 ) );如何计算数组元素的个数:
元素个数 = 整个数组大小 / 某个元素的大小
2 int num = sizeof(arr) / sizeof(arr[0]) ;
如何得出数组的元素下标的最大值:
1 元素最大下标 = 整个数组大小 / 某个元素的大小 - 1
2 int num = sizeof(arr) / sizeof(arr[0]) - 1;
实例:
1
int arr
[]
=
{
1
,
2
,
3
,
4
,
54
,
6
,
7
,
325
,
3
,
4
,
5
} ;
字符数组:
概念: 字符数组是一个专门用来存放字符类型输数据的数组。
定义、初始化:
char TieZhu [ 10 ] ; // 完全没有初始化,他的值为随机值
char TieZhu [ 10 ] = {0}; //部分初始化 , 0 表示字符的ASCII值 ,char a = 97
char TieZhu [ 10 ] = {'\0'}; // 部分初始化,‘\0’表示字符
char TieZhu [ 10 ] = {'0'}; // 部分初始化,‘0’表示字符 ASCII 为 48
char TieZhu [ 10 ] = {"Hello"}; // 字符串数组
char TieZhu [ 10 ] = {'H' , 'e' , 'l' ,'l' , 'o'}; // 字符数组
char TieZhu [ ] = {"Hello"}; // 字符串数组
char TieZhu [ ] = {'H' , 'e' , 'l' ,'l' , 'o'}; // 字符数组
元素引用:
练习:
给定一个字符串
"Hello World!!!"
通过代码来计算该字符串的
长度
。
法一:
#include <stdio.h>
int main()
{
char arr2[] = "Hello World!!!";//字符串是以'\0'作为结束符
int i;
for (i = 0; i < sizeof(arr2)/sizeof(arr2[0]); i++)
{
if (arr2[i] == '\0')
break;//跳出循环体
}
printf("arr2=%d\n",i+1);
return 0;
}
法二:
#include <stdio.h>
int main()
{
char arr2[] = "Hello World!!!";
int i=0;
while (arr2[i]!='\0')
{
i++;
}
printf("arr2=%d\n",i+1);
return 0;
}
拓展从键盘获取一个用户随机输入的一句话然后程序计算长度
.
#include <stdio.h>
int main()
{
char arr2[1024];
printf("从键盘输入一句话:\n");
//scanf("%s",&arr2);scanf不能接受空格、制表符Tab、回车等;而gets能够接受空格、制表符Tab和回车等;故此题用gets 输入函数。
gets(arr2);
printf("%s\n",arr2);
int i=0;
while (arr2[i]!='\0' || arr2[i]==' ')
{
i++;
}
printf("arr2=%d\n",i+1);
return 0;
}
字符串长度计算的函数:
strlen 的作用: 用来计算字符串的长度并返回长度
注意: 该函数计算字符串长度的时候遇到结束符即停止,并
结束符不计入长度内
。
头文件:
#include <string.h>
函数原型:
size_t strlen(const char *s);
参数分析:
s --> 需要计算长度的字符串的入口地址
返回值:
成功 返回该字符串的长度(不包含结束符)
注意:
msg = "Even"; // [ 错误 ] 不允许对数组名直接赋值
// 初始化后 如果需要对数组进行重新复制,只能一个一个元素进行赋值
msg[0] = 'E';
msg[1] = 'v';
msg[2] = 'e';
msg[3] = 'n';
int arr[] = {1,2,3,4,5}; // 初始化语句允许进行整体赋值
arr = {6,7,8,9,10} ; // 离开初始化语句后不允许的数组进行整体赋值,只能也一个一个元素地赋值
//也可以使用循环体进行赋值
越界访问:
当一个数组的大小定义的时候设置为10 ,但是访问该数组的时候 超过了原本申请的大小10 甚至
更多的时候就称为越界访问。
越界访问一定会出问题吗?
不一定!!
越界访问
不一定是非法
的。
非法访问用是越界的。
练习:
假设给定一个整型数组 { 6 , 4 , 27 , 23 , 6 , 56 , 1 , 3 } , 尝试使用排序算法将他进行重新排序后
输出。
冒泡排序:
#include <stdio.h>
int main()
{
int arr1[]={1,2,1234,34,54,6,86,8,8,23,214};
int i,j,temp=0;
for(i=0;i<sizeof(arr1)/sizeof(arr1[0])-1;i++)//外循环,记录没次比较后所减少的比较次数
{
for(j=0;j<(sizeof(arr1)/sizeof(arr1[0])-1-i);j++)//内循环,进行两两比较
{
if(arr1[j]>arr1[j+1])
{
temp=arr1[j+1];
arr1[j+1]=arr1[j];
arr1[j]=temp;
}
}
}
for(int i=0;i<sizeof(arr1)/sizeof(arr1[0]);i++)//输出比较后,数组所存储的数值
{
printf("%d ",arr1[i]);
}
return 0;
}
拓展:
从键盘直接输入数据,并完成排序。
作业:
1、
使用数组的知识点尝试实现把一个字符串数组进行翻转
输出
#include <stdio.h>
int main()
{
char arr2[1024];
printf("从键盘输入一句话:\n");
gets(arr2);
printf("%s\n",arr2);
int i=0;
while (arr2[i]!='\0')
{
i++;
}
printf("arr2=%d\n",i+1);
for(;i>=0;i--)
{
printf("%c",arr2[i]);
}
printf("\n");
return 0;
}
3. 键盘随机输入一串字符串,程序检查并去掉相邻的重复字符后输出
1
输入:
hello google
2
输出:
helo gogle
二维数组
指针
笔试题的注意事项:
不/考虑
空间(内存)
的问题
是否可以使用第三个变量 (是否可以创建新的变量)
是否可以使用第二个数组(可不可以在原有基础上创建新的数组)
链表.......
不考虑
效率
的问题
拓展如何在标准输入字符串时输入空格以及TAB 按键:
默认情况下
空格
以及
Tab
按键会作为scanf 的结束标记。
方法1 :
正则表达式:
scanf("%[^\n]" , msg) ;
%[^\n] --> 表示在输入数据的时候只要不是换行符 \n 都允许
方法2 :
不使用scanf ,改为 fgets
功能:
从指定的某一个文件中获取一条字符串(以 \0 、 \n 为结束符)
头文件:4 #include <stdio.h>
函数原型:
char *fgets(char *s, int size, FILE *stream);
参数分析:
s --> 获取到的字符串所存放的内存地址(数组名)
size --> 表示你希望获取的字符串的最大尺寸(数组的大小尺寸)
stream --> 从那个文件中获取
返回值:
成功 返回指针s (数组的入口地址)
失败 返回NULL
练习:
用户从键盘随意数组字符或数字,程序计算得出用户输入的所有小写字符、空格、大写字符、符号
的数量
1
输入:
Hello Even
GZ2207
@
2
输出:
3
空格:
2
4
小写字符:
7
5
大写字符:
4
6
数字:
4
7
符号:
1
多维数组:
概念: 如果一个数组的元素也是一个数组那么该数组就是多维数组(二维数组)
语法:
1 int arr [3] [ 5 ] ;
解读:多维数组如何定义以及初始化:
// 定义一个数组名为 arr 他一共有3个元素,
// 每一个元素都是一个数组,该数组有5个元素每一个元素都是整形的。
int arr [3][5] ;
int arr [3][5] = { 1,2,3,4,5,6,7,8,9,10 }; // 该数组的元素有 3×5个 因此该初始化未完全,未初
int arr [3][5] = { {} , {} , {1,2,3,4,5} };
多维数组的引用:
int arr [3][5] = { 1,2,3,4,5,6,7,8,9,10 };
printf("arr[0][3]:%d\n" , arr[0][3]);
问题:
int arr [100][25] ; 请输出第 365个元素的值???
365 / 25 ---> 得出第几组 N
365 % 25 --> 得出在该组中的偏移量 M - 1
arr[N][M] ;
拓展:
临界值的问题
1
int arr
[
3
][
5
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
};
2
如何写出第十个数据的值??
数组的万能拆解方法:
任意一个数组不管有多复杂都可以通过该方法来拆解分析
第一部分: 说明数组的名字已经他的元素个数
第二部分: 说明该数组的元素是什么类型的数据
1
char arr
[
3
][
5
][
6
] ;
//
第一部分
arr [3] ,
第二部分
char [5][6]
2
int
(
*
arr
[
3
]) (
int
,
float
) ;
//
第一部分
arr[3] ,
剩下的是第二部分