一、数组
数组:使用一段连续的存储空间存储类型相同的构造类型
构造类型:可以分割(数组,结构体,共用体)
int a,b,c,d,e;
-->int arr[5];
1.一维数组
一维数组:使用一个下标表示的数组称为一维数组
1.1一维数组的定义格式
格式: 存储类型 数据类型 数组名[常量表达式]
1.存储类型:
auto/static/extern/register/const/volatile
auto 动态变量
stastic 静态变量 延长局部变量的生命周期
extern 引用外部变量
register 寄存器变量 不可做取地址操作
const 修饰词 修饰的变量值不可变
voiatile 修饰词 防止内存优化,保持内存的可见性
2.数据类型: 基本类型, 构造类型,空类型,指针类型
3.数组名:满足命名规范(字母,数字,下划线)
4.: []是数组的标志
5.常量表达式:表示数组元素的个数,定义时不为0,不为空,不为小数,初始化不为变量
int arr[5];//auto int arr[5];存储了5个整数,整个数组arr的类型是int.
int arr[0];//没有意义,编译不会报错,调用会出错
int arr[]//error
int arr[5.5]//error
int n=5;int arr[n];//正确的
int n=5;int arr[n]={1,2,3,4,5};//可变大小的数组不能初始化
1.2 一维数组的定义以及初始化、赋值
1.一维数组的全部初始化
int arr[5]={22,25,5,88,74};
2.一维数组的部分初始化,剩余元素使用0填充
int arr[5]={11,22};
int arr[5]={0};//对数组清零
arr[0]=11;
arr[1]=22;
3.一维数组的单个赋值
int arr[5];
arr[3]=9;
arr[2]=11;
//剩余元素默认是随机值
4.省略数组长度初始化
int arr[]={11,22,22,66,55,42,8,1};
int arr[6]={1,54,22,55,41,21};//数组长度默认是实际元素的个数
5.memset 实现对整型数组清0和-1
格式:
参数:
void *s:表示数组变量名
int c:清的值:0,-1,其他会乱码
size_t n:表示数组的字节大小
64 size_t --->#define size_t unsigned long
在64位操作系统size_t 表示unsigned long类型
32 size_t --->#define size_t unsigned int
在32位操作系统size_t 表示unsigned int类型
6.bzero 实现对数组清0
格式:
参数:
void *s:表示数组变量名
size t n:表示数组的字节大小
7.数组的错误初始化
int arr[5];arr[5]={1,2,3,4,5};
int arr[5];arr={1,2,3,4,5};
int arr[5]={1,2,3,4,5,6,7,8};
1.3 一维数组的引用
1.数组下表从0开始,n元素的数组,下标[0,n-1]
int arr[5];arr[0]——arr[4]
2.数组元素的引用
3、数组的循环引用
int arr[5];
int i;
//i:下表
//arr[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]);
4、数组的越界引用
int arr[5];
printf("arr[5]=%d\n",arr[5]);
1.如果越界访问的内存没有被占用,可以访问,访问的结果是随机值
2,如果越界访问的内存被占用,存储不重要的数据,可以访问,访问的结果是随机值
3.如果越界访问的内存被占用,存储重要的数据,不可以访问,段错误
段错误:访问了不该访问的内存空间
1.4 一维数组的地址
1.数组的地址是连续
2.数组名表示数组的首地址,也就是第一个元素的地址arr-->&arr[0]
地址输出占位符 %p
2.多维数组\二维数组
二维数组:使用两个下表表示的数组称为二维数组
2.1 二维数组的定义格式
格式:存储类型 数据类型 数组名[常量表达式1][常量表达式2]
1、常量表达式1: 第一维,表示行,在初始化时可有可无
2、常量表达式2:第二维,表示列,必须存在
int arr[3][5];// 3行5列,存储15个整数
arr的字节大小是3*5*4,arr的类型是int [3][5]
2.2 二维数组的初始化以及赋值
1.二维数组的全部初始化
int arr[2][3]={{1,2,3},{4,5,6}} //按行初始化
int arr[2][3]={1,2,3,4,5,6};//{}可以省略不写,按列
int arr[][3]={1,2,3,4,5,6};//当初始化时,可以省略第一维,计算机不扫描第一维
2.二维数组的部分初始化,剩余元素填充0
int arr[2][3]={{1,0,0},{4,5,0}} //按行初始化
int arr[2][3]={1,4,5,0,0,0};//{}可以省略不写,按列
int arr[][3]={1,2,0};//当初始化时,可以省略第一维,计算机不扫描第一维
int arr[][3]={{1},{2}};//2行
2.3二维数组的引用
1.数组下表从0开始,m行n列的二维数组,行下表[0,m-1]列表[0,n-1]
int arr[m][n];
最后一个元素:m-1,n-1
2.二维数组元素
arr[0][0]:第一行第一列的值
ar[i][j]:第i+1行,j-1列的值
3.二维数组的应用
(1)二维数组实现杨辉三角
数组arr[i][0]==1每一列的第一个元素为1
数组arr[n][n]==1:每一行的最后一个元素为1
数组arr[i][j]==arr[i-1][j]+arrr[i-1][j-1]:三角里面的元素为上一行列数相近的两元素相加
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
int n;
printf("杨辉三角的行数:");
scanf("%d",&n);int i,j;
n=n+1;
int arr[n[n];
bzero(arr,sizeof(arr));//数组清零
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
if(j==0llj==i)//每一行的起始元素和结尾元素为1t
{arrfi][i]=1:}
else//三角里面的其他元素判定
{
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
printf("%d",arr[i][j]);//循环输出
}
putchar(10);//换行
}
return 0;
}
(2)二维数组转置(行转列)
int main()
{
int a[2][3]={1,2,3,4,5,6};
int b[3][2],i j;
//循环数组a存储到b
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
b[j][i]=a[i][j];
}
}
//循环输出数组b
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
{
printf("%d ",b[i][j]);
}
putchar(10);
}
return 0;
}
3.一维字符数组
格式: 存储类型 char 数组名[常量表达式]
char str[10]; //存储10个字符,整体成为1个字符串
字符数组:存储一个或多个字符的容器字符串:0个或多个字符的整体(标志是"0,不是双引号,一般字符串多使用双引号引起来)
"A”""+-234”"你好"'A’'AB'
char str10]="hello";
字符数组>字符串,字符数组存储字符串
3.1 字符数组的定义以及初始化
1.单字符初始化
char str[5]={'a','b','c','d','e'};//单字符的全部初始化
char str[5]={'a','b',0,0,0};//单字符的部分初始化,剩余元素使用\g填充
char str[5]={'a','b','\0','\0','\0'};
char str[]={'a','b','c','d'};//省略数组长度,默认是实际元素的个数
2、字符串初始化
char str[5]={"abcd"};//字符串的全部初始化,当双引号引起来,计算机自动添加\0
char str[5]="abcd";//当双引号引起来是,{}可以省略不写
char str[5]="ab\0\0\0";//字符串的部分初始化,剩余元素使用\0填充
char str[5]="";//字符串清θ(个人推荐定义字符数组的时候用)
char str[]="abc";//省略数组长度,默认是实际元素的个数+1
3、字符串的错误初始化
char str[5]="abcde";x
char str[5];str="abcd";x
char str[5];strcpy(str,"abcd");//√
3.2一维字符数组的引用
1、字符的单个引用
int i;
for(i=0;i<strlen(str);i++)
for(i=0;str[i]!='\0';i++)
{printf(“%c",str[i]);}
2、字符串的整体引用
char str[10];
scanf("%s",str);
//整体引用需要%s-->遇到\0结束
printf(“%s",str);//从首地址开始遇到\0结束
3、gets/puts实现字符串输入输出
scanf和gets的区别?
1.scanf不可以输入空格,gets可以输入空格
2.scanf可以输入一个或多个任意类型,gets只可以输入一个字符串
3.scanf属于格式解析,gets属于键盘读取,gets的输入速度大于scanf
printf和puts的区别?
1.printf默认没有换行,puts自带换行
2.printf可以输出一个或多个任意类型,puts只可以输出一个字符串
3.printf属于格式解析,puts属于键盘读取,puts的输出速度大于printf
3.3 字符数组长度和字符串长度
字符数组长度sizeof:实际字符的个数+1,计算\0
字符串长度stren:计算实际字符的个数,遇到0结束,不计算\0
3.5函数族
1.strlen
功能:计算字符串长度,遇到\0结束
格式:
#include <string.h>
size t strlen(const char *s);
参数:
const char *s:表示字符数组变量名
返回值:
size t
在64操作系统 unsigned long--->#define size t unsigned long
在32操作系统 unsigned int--->#define size t unsigned int
2.strcpy
功能:实现字符串拷贝--->赋值
格式:
#include<string.h>
char *strcpy(char *dest,const char *src);
参数:
char *dest:目标字符串,改变
const char *src:源字符串,不变
把src拷贝给dest
3.strcat
功能:实现字符串连接
格式:
#include <string.h>
char *strcat(char *dest,const char *src);
参数:
char *dest:目标字符串,改变
const char *src:源字符串,不变
把src连接到dest的后面
4.strcmp
功能:字符串比较
格式:
#include <string.h>
int strcmp(const char *s1,const char *s2);
参数:
s1:第一个字符数组变量名
s2:第二个字符数组变量名
返回值:
int:表示s1-s2的ASCII差值
3.6补充函数atoi
功能:实现字符串转换整数
格式:
#include <stdlib.h>
int atoi(const char *nptr);
参数:
const char *nptr:表示字符数组变量名
返回值:
int 表示返回的整数
使用格式:
char a[]="123'
atoi(a);--->123
4.二维字符数组
格式: char 数组名[常量表达式1][常量表达式2]
eg: char str[3][5]
常量表达式1:第一维,可有可无,行,字符串的个数
常量表达式2:第二维,必须存在,列,每个字符串所占的字节大小
char a; //存储一个字符
char b[10];//存储10个字符,一个字符串
char c[3][5];//存储3个字符串,每个字符串5字节
4.1 二维字符数组的定义以及初始化
1.字符串初始化
char a[3][5]={"abcd","1234","+-*/"};//字符串全部初始化
char a[3][5]={"ab","1","+"};//字符串部分初始化,剩余元素使用\0填充
char a[][5]={"ab",“1","+"};//省略第一维,默认是3行
2.单字符初始化
char a[2][3]={{'a','b','c’},{'1','2','3'}};