数组
概念:具有一定顺序的若干变量的集合
定义格式:存储类型 数据类型 数组名[元素的个数]
例:int arr[5];//定义了一个数组arr,在内存空间中开辟了5个空间来存储值,在数组中保存的每一条数据都叫元素(变量)
数组名:代表数组的首地址(地址常量);数组名不能被重新赋值,不能为左值
数组的访问:数组名[下标]
int arr[5]={1,2,3,4,5};
arr[0]; ---》1
arr[2];----》3
arr[5-1];----》5
访问第n个元素:数组名[n-1]
修改数组里面元素:数组名[下标]=新值
arr[0]=100;
数组越界:
int a[3]={0,1,2,3};------》数组越界
int a[3]={1,2,3};
a[3]-----》数组越界 //int a[3]中的3是开辟3个空间,a[3]是指数组a中第四个元素,而只开辟了3个空间,第四个元素属于越界
注意:
-
特点:
- 数据类型相同---定义int类型数组,数组中每一个元素都是int类型
- 内存连续
- 数组名[下标]--->变量名 数组内的元素----->变量的值
- 数组名的命名要符合标识符的命名规范
- 在同一个函数中,变量和数组名不能同名 //int a[3];int a;//错误
- 数组名的下标从零开始,最后一个元素的下标是n-1
- 数组名是地址常量
代码验证位置:
//int为4字节
//char为1字节
分类:
一维数组 二维数组
一维数组:
定义格式:存储类型 数据类型 数组名[元素的个数]
访问:数组名[下标]
初始值:
- 全部初始化:
int a[3]={1,2,3};
2.未初始化:后续赋值只能单个元素
int a[3]; //随机值
a[0]=1;
a[1]=2;
a[2]=3;
3.部分初始化:未初始化部分值为0
int a[3]={1,2}//1,2,0
int arr[5]={1,2}//1,2,0,0,0
定义空数组:
- int a[3]={0,0,0};
- int a[3]={0};
- int a[3]={};
引用:(访问)
- 先定义后引用
- 每一次访问只能访问一个值 a[i],如果想引用数组中所有的元素可以选择遍历(使用循环)
- 引用时防止数组的越界,虽然编译器有时不会报错
- 对于数组中每一个元素的地址的打印使用%p格式
- 内存分配
数组的遍历:
数组名[下标]--->0 1 2 3
输出数组中的元素:
输入元素保存到数组中:
练习:
对数组进行求和
数组的大小(内存空间的大小):
int a[3];//开辟12个字节
- 数据类型的大小*元素的个数
- sizeof(数组名)
计算元素个数:
1.直接观察
2.sizeof(数组名)/ sizeof(数组的类型)
清零函数
bzero
#include <strings.h>
void bzero(void *s, size_t n);
功能:将数组的内存空间设置为0
参数:s:要清空的数组的首地址
n:数组的大小(字节)
返回值:无
memset
#include <string.h>
void *memset(void *s, int c, size_t n);
功能:将数组的内存空间设置为某一个值 0
参数:s:要清空的数组的首地址
c:你要设置的值
n:数组的大小(字节)
返回值:清空的数组的首地址
字符数组:
概念:字符数组的里面存放的都是字符 实际存放的是字符串
格式:
char str[3]={'a','b','c'};//逐个字符赋值
char str[]={'a','b','c'};//逐个字符赋值 数组的大小:3 元素个数:3
char str[]="hello";//使用字符串赋值 数组的大小:6 系统添加\0
char str[32]="hello"//使用字符串赋值 数组的大小:32
注意: 使用字符串赋值时会省略后期的\0 ---- 数组越界
char s[5]="helllo" //越界
字符数组的输入输出:
1.for循环
格式:%c
2. 直接使用%s输出
遇到‘/0’停止
解决:%[^\n] \\直到遇到\n结束
3.输出:puts
int puts(const char *s);
功能:向终端输出一个字符串
参数:字符串的首地址
返回值:输出字符的个数(包含\0)
输入: gets
#include <stdio.h>
char *gets(char *s);
功能:从终端输入一个字符串
参数:s:字符数组的首地址 (字符串保存位置)
返回值:字符数组的首地址
gets:不关注数组越界的问题
计算字符串的实际长度
1.循环
2.strlen
#include <string.h>
功能:计算字符串的实际长度(不包含\0)
参数:要计算的字符串的首地址
返回值:字符串的实际个数
sizeof和strlen的区别:
- sizeof计算开辟内存空间大小的 strlen计算字符串的实际长度
- sizeof关键字 strlen是函数
- sizeof计算时会计算\0 strlen不会
二维数组:
格式:存储类型 数据类型 数组名[行数][列数]
例:int arr[2][3];//两行三列二维数组
int arr[2][3]={1,2,3,4,5,6};
访问:数组名[行下标][列下标]
第1行第1列 第一个元素:arr[0][0]----行下标 列下标 都是从零开始
第2行第1列元素:arr[1][0]
第2行第3列元素:arr[1][2]---->arr[行数-1][列数-1]
行和列都不能越界
int arr[][3]={1,2,3,4,5,6,7};对
int arr[2][]={1,2,3,4};错误
定义时行数可以省略但是列数不可以
数组的元素个数:
个数=行数*列数
二维数组大小:
- 大小=行数*列数*数据类型的大小
- sizeof(数组名)
数组名:
数组名 arr:第一行的首地址
arr+1:第二行的首地址
arr[0]: 第一行第一列的首地址
初始化:
1.全部初始化:
int arr[2][3]={1,2,3,4,5,6};//顺序赋值
int arr[2][3]={{1,2,3},{4,5,6}};//按行存储
2.部分初始化:未赋值部分为0
int arr[2][3]={1,2,3,4};//顺序赋值 123400
int arr[2][3]={{1,2},{4}};//按行存储 120400
3.未初始化:值--随机值,后期赋值单独进行
int arr[2][3];
arr[0][0]=1;arr[0][1]=1;
存储:
二维数组的遍历:
双重for:外层循环控制行 内层控制列
int a[2][3]={1,2,3,4,5,6};
for (int i = 0; i < 2; i++)
{
for (int j= 0; j < 3; j++)
{
// scanf/printf
printf("%d ",a[i][j]);
}
}