一、数组的定义
数组:使用连续的储存空间存储多个类型相同的构造类型
数据类型:基类型(int float)、构造类型(数组,结构体,共用体)、空类型(void)、指针类型
二、一维数组
1.一维数组的定义
1.全局变量未初始化默认结果为0
在main函数外定义的变量,全局
2.局部变量未初始化默认结果为随机值
在main函数内定义的变量,局部
3.全部初始化
int arr[5]= {1,2,3,4,5};
4.部分初始化,默认剩余元素使用0填充
int arr[5]= {1,2};
int arr[5]= {0}; //对数组清0
5.单个数组元素初始化。默认剩余元素是随机值
int arr[5];
arr[0]=11;
arr[1]=22;
arr[3]=44;
6.省略数组长度初始化,默认数组长度是实际元素的个数
int arr[5]={11,22,33,44,55};
int arr[]={11,22,33,44,55};
7.对数组清0
// memset:对字符初始化,可以对整数进行清0和-1
函数格式:
#include <string.h>
void *memset(void *s, int c, size_t n);
参数:
void *s: 标识数组名
int c : 初始化的值
size_t n : 数组的字节大小
使用格式:
int arr[5];
memset(arr, 0, sizeof(arr)); //对数组清0
// bzero: 专门清0
函数格式:
#include <string.h>
void bzero(void *s, size_t n);
参数:
void *s: 表示数组名
size_t n: 数组的字节大小
使用格式:
int arr[5];
bzero(arr, sizeof(arr));
8.错误初始化
int arr[5];
arr = {1,2,3,4,500}; //× arr:数组名表示数组的首地址
arr[5]={11,22,33,44,55};//× arr[5]是一个值,且越界
2.一维数组的引用
1.一维数组下表从0开始,n个元素,下表的取值范围[0,n-1]
2.数组元素的引用
arr[0] 第一个值
arr[1] 第2个值
3.数组的越界访问
如果越界访问的内存没有被占用,可以访问,结果是随机值
如果越界访问的内存被占用,存储不重要数据,可以访问,结果随机值
如果越界访问的内存被占用,存储重要数据,不可以访问,结果 段错误
4.数组的循环引用
int arr[5];
int i;
//循环输入
for(i=0;i<5;i++)
{
scanf("%d",&arr[i]);
}
//循环输出
for(i=0;i<5;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
3.数组的地址
数组名表示数组的首地址,也就是第一个元素的地址
int arr[5]; arr===>&arr[0]
代码如下:
{ int arr[3]={11,22,33}; //打印地址 //arr+i-->&arr[i]--->&arr[0]+i for(int i=0;i<3;i++) { printf("%p\n",arr+i); printf("%p\n",&arr[i]); printf("%p\n",&arr[0]+i); } return 0; }
三、二维数组
1.二维数组的定义以及初始化
1.二维数组按行初始化
int arr[2][3]={{11,22,33},{44,55,66}}; //全部初始化
int arr[2][3]={{11,0,0},{44,55,0}}; //部分初始化,剩余元素使用0填充
2.二维数组按列初始化
int arr[2][3]={11,22,33,44,55,66}; //全部初始化
int arr[2][3]={11,22,0,0,0,0}; //全部初始化
3.二维数组省略第一维初始化
int arr[][3]={11,22,33,44,55,66}; //全部初始化
int arr[][3]={11,22,0}; //全部初始化 1行
int arr[][3]={{11},{33}}; //全部初始化 2行
4.计算行和列
int arr[][3]={11,22,33,44};
int line=sizeof(a)/sizeof(a[0])
int row=sizeof(a[0])/sizeof(a[0][0])
5.二维数组的错误初始化
int arr[2][3];
arr={11,22,33,44,5};
arr[2][3]={11,22,33};
2.二维数组的引用
1.数组下表从0开始,m行n列:行[0,m-1] 列[0,n-1]
2.引用二维数组元素
int arr[2][3]={11,22,33,44};
arr[0][0]=11
2行3列:arr[1][2]
3.二维数组的循环引用
//循环输入二位数组
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
{
scanf("%d",&arr[i][j]);
}
}
//循环引用二位数组
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
{
printf("arr[%d][%d]=%d\n",i,j,arr[i][j]);
}
}
4.数组的越界访问
如果越界访问的内存没有被占用,可以访问,结果是随机值
如果越界访问的内存被占用,存储不重要数据,可以访问,结果随机值
如果越界访问的内存被占用,存储重要数据,不可以访问,结果 段错误
3.二维数组的地址
二维数组的地址是连续的
int main(int argc, const char *argv[]) { int arr[2][3]; for(int i=0;i<2;i++) { for(int j=0;j<3;j++) { printf("%p\n",&arr[i][j]); } } return 0; }
四、一维字符数组
1.字符数组定义以及初始化
1.单字符初始化
char str[5]={'a','b','c','d','e'}; //全部初始化
char str[5]={'a','b','c'}; //部分初始化,剩余元素默认使用'\0'填充
char str[]={'a','b','c'};//默认是实际字符的个数
2.字符串初始化,双引号引起来,计算机会默认添加\0
char str[5]={"abcd"};//全部初始化
char str[5]="abcd";//{}可有可无
char str[5]={"ab"};//部分初始化,剩余元素默认使用'\0'填充
char str[]="abcd"; //默认长度是5
3.错误初始化
char str[5];str="abcd"; ×
char str[5];str[5]="abcd"; ×
2.一维字符数组的引用
1.使用一维数组的循环引用
char str[5]="abcd";
2.字符串的整体引用%s
char str[5]="abcd"; //整体输入
scanf("%s",str); //只有字符串的输入不加&
printf("%s",str);//%s格式控制符,打印字符串,遇到\0自动结束
3.字符数组长度和字符串长度的区别(面试)
字符数组长度:使用sizeof计算,计算\0
字符串长度: 使用strlen计算,不计算\0
字符数组长度
字符串长度
char a[]="abcd"
5 4 char b[]={'a','b','c'}
3 随机 char d[10]={'a','b'}
10 2 char e[100]="abcd"
100 4 char g[]="abc\0gh"
7 3
4.字符串函数
1.strlen
功能:计算字符串长度,不计算\0
格式:
#include <string.h>
<>:默认在系统库文件中查找 /usr/include
"":现在当前目录下查找头文件,如果找不到在系统库文件中查找
size_t strlen(const char *s);
参数:
char *s:表示数组变量名
返回值:
#define size_t unsigned long -->64位-->%ld %lu
#define size_t unsigned int --->32位-->%d %u
默认返回字符串长度
使用格式:
char str[]="hello";
strlen(str); // 5
strlen("hello"); // 5
非函数实现:
//非函数的实现方式
size_t i=0;
for(i=0;str[i]!='\0';i++);
printf("i=%ld\n",i);
2.strcpy
功能:字符串拷贝,字符串赋值
函数格式:
#include <string.h>
char *strcpy(char *dest, const char *src);
参数:
char *dest:目标字符串
const char *src:源字符串
把src字符串拷贝给dest,dest变,src不变
返回值:
返回dest的首地址
使用格式:
char a[]="hello";
char b[10]=""
strcpy(b,a);
把a的值赋值给b
strcpy(b,"hello");
//非函数实现字符串拷贝
char dest[10]="12345678";
char src[10]="abcd";
int i;
for(i=0;src[i]!='\0';i++) {
dest[i]=src[i];
}
dest[i]='\0';
puts(dest);
3.strcat
功能:字符串连接
格式: #include <string.h> char *strcat(char *dest, const char *src); 参数: char *dest:目标字符串 const char *src:源字符串 把src连接到dest的后面,dest变,src不变 返回值: 返回dest的首地址 使用格式 : char a[20]="hello"; char b[20]="world"; strcat(a,b); //把b连接到a的后面 strcat(a,"world"); //非函数实现字符串链接 char dest[20]="123456"; char src[]="abcdef"; //循环到dest的后面 int i; for(i=0;dest[i]!='\0';i++); //循环src复制给dest int j; for(j=0;src[j]!='\0';j++) { dest[i++]=src[j]; } dest[i]='\0'; puts(dest);
4.strcmp
功能:字符串比较
格式: #include <string.h> int strcmp(const char *s1, const char *s2); 参数: const char *s1: 第一个字符数组变量名 const char *s2: 第二个字符数组变量名 参数: int: 表示s1-s2的ASCII值 使用格式: char a[]="AB"; char b[]="AB"; a<b -->strcmp(a,b)<0 -->-32 if( strcmp(a,b)<0) if(a<b) a>b --->strcmp(a,b)>0 -->32 a==b -->strcmp(a,b)==0--->0
五、二维字符数组
格式:存储类型 char 数组名[常量表达式1][常量表达式2]
常量表达式1:第一维,行,字符串的个数
常量表达式2:第二维,列,每个字符的字节大小
char a; //一个单字符
char b[10]; //10个单字符, 一个字符串
char str[3][5]; //3行5列 3个字符串,每个字符串5字节
1.单字符初始化 char a[2][3]={{'A','B','C'},{'1','2','3'}}; 按行的全部初始化 char a[2][3]={'A','B','C','1','2','3'}; 按列全部初始化 char a[2][3]={'A','B','C','1'}; 部分初始化 2.字符串整体初始化 char a[3][5]={"ABCD","1234","+-*/"};