目录
数组类型
数组变量
数组特性
一维数组
二维数组
数组拓展
字符处理
什么是数组?
数组是一种用于存储相同类型数据的容器
数组可以存储多个具有相同数据类型的元素,并通过索引访问这些元素
数组的大小在创建时就被固定下来,无法在运行时改变
声明和初始化数组
//type arrayName[arraySize];
type是指数组元素的数据类型,arrayName是数组的名称,arraySize是数组的大小(表示数组可以容纳的元素数量)
在声明数组后,可以通过索引来访问数组的各个元素。第一个元素的索引为0,第二个元素的索引为1,以此类推。
数组还可以在声明时进行初始化,即在创建数组的同时为其赋初值。
int numbers[5] = {1, 2, 3, 4, 5}; // 初始化数组的同时指定元素的值
int numbers[] = {1, 2, 3, 4, 5}; // 省略数组大小,由编译器自动确定
int numbers[5] = {1}; // 只给第一个元素赋值,其他元素自动初始化为0
访问数组元素
要访问数组中的元素,可以使用数组名称和索引。索引用于指定要访问的元素的位置。
数组的遍历
使用循环结构可以遍历数组中的所有元素。常见的循环结构是for循环。
for (int i = 0; i < arraySize; i++)
{
// 访问数组元素
// 使用 numbers[i] 进行操作
}
注意事项
数组的索引从0开始,因此最后一个元素的索引是数组大小减1。
避免访问超出数组界限的元素,这可能导致未定义的行为。
数组的大小在创建时就被固定下来,无法在运行时改变。
数组名实际上是一个指向数组首元素的指针,可以将数组名视为指针常量
区别与特征
数组内存地址
数组首地址第一个元素的地址-可以使用数组名(没有索引)作为数组的地址
#include
#include
int main()
{
//变量定义
int Num = 100;
printf("%d \r\n", Num);
//数组定义
int Arr[5] = { 1,2,3,4,5 };
//数组名为数组首地址(第一个元素地址)
printf("%p \r\n", Arr);
printf("%p \r\n", &Arr[0]);
return 0;
}
数组内存大小
数组的总内存大小是每个元素的大小乘以元素的数量-使用sizeof运算符-你可以得到整个数组的大小和一个元素的大小
#include
#include
int main()
{
//变量定义
int Num = 100;
printf("Size -> %d \r\n", sizeof(Num));
//数组定义
int Arr[5] = { 1,2,3,4,5 };
//数组元素个数 * 单个元素大小
printf("Size -> %d \r\n", sizeof(Arr));
return 0;
}
数组元素个数
数组的元素数量可以通过数组的总大小除以一个元素的大小来计算
#include
#include
int main()
{
//变量定义
int Num = 100;
printf("Size -> %d \r\n", sizeof(Num));
//数组定义
int Arr[6] = { 1,2,3,4,5 };
//元素个数
printf("Conut -> %d \r\n",/*数组大小 / 单个大小 = 元素个数*/ sizeof(Arr) / sizeof(Arr[0]));
//遍历数组
for (int i = 0; i < sizeof(Arr) / sizeof(Arr[0]); i++)
{
printf("%d \r\n", Arr[i]);
}
return 0;
}
定义方式
数据类型 数组名[ 数组元素 ];
数据类型 数组名[ 数组元素 ] = { 值1,值2 ...};
数据类型 数组名[] = { 值1,值2 ...};
数组特点
C语言当中下标是从0开始的
如果部分初始化数组,剩余的元素就会被初始化为0。
如果初始化数组时省略方括号中的数字,编译器会根据初始化列表中的项数来确定数组的大小
数组定义
#include
#include
int main()
{
//数据类型 数组名[ 数组元素 ] = { 0 };
//全部元素赋值为0
int Arr1[5] = { 0 };
//数据类型 数组名[ 数组元素 ] = { 值1,值2 ...};
//元素4-5用0填充
int Arr2[5] = { 1,2,3 };
//数据类型 数组名[] = { 值1,值2 ...};
int Arr[] = { 1,2,3,4 };
return 0;
}
定义方式 -> type array_name[row_size][column_size];
常见样式
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数组布局
示例代码
#include
#include
int main()
{
//数据类型 数组名[ 行数 ][ 列数 ];
int Arr1[2][3];
Arr1[0][0] = 1;
Arr1[0][1] = 2;
Arr1[0][2] = 3;
Arr1[1][0] = 4;
Arr1[1][1] = 5;
Arr1[1][2] = 6;
for (size_t i = 0; i < 2; i++)
{
for (size_t j = 0; j < 3; j++)
{
printf("%d \r\n", Arr1[i][j]);
}
}
//数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
int Arr2[2][3] =
{
{11, 22, 33},
{44, 55, 66},
};
for (size_t i = 0; i < 2; i++)
{
for (size_t j = 0; j < 3; j++)
{
printf("%d \r\n", Arr2[i][j]);
}
}
//数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
int Arr3[2][3] = { 77,88,99,11,22,33 };
for (size_t i = 0; i < 2; i++)
{
for (size_t j = 0; j < 3; j++)
{
printf("%d \r\n", Arr3[i][j]);
}
}
//数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
int Arr4[][3] = { 111,222,333,444,555,666 };
return 0;
}
数组元素
#include
int main()
{
//定义了一个二维数组,名字叫a
//每个元素又是一个一维数组int[4]
int a[3][4] = { 1, 2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12 };
//数组名为数组首元素地址,二维数组的第0个元素为一维数组
//第0个一维数组的数组名为a[0]
printf("a = %p\n", a);
printf("a[0] = %p\n", a[0]);
//测二维数组所占内存空间,有3个一维数组,每个一维数组的空间为4*4
//sizeof(a) = 3 * 4 * 4 = 48
printf("sizeof(a) = %d\n", sizeof(a));
//测第0个元素所占内存空间,a[0]为第0个一维数组int[4]的数组名,4*4=16
printf("sizeof(a[0]) = %d\n", sizeof(a[0]) );
//测第0行0列元素所占内存空间,第0行0列元素为一个int类型,4字节
printf("sizeof(a[0][0]) = %d\n", sizeof(a[0][0]));
//求二维数组行数
printf("i = %d\n", sizeof(a) / sizeof(a[0]));
// 求二维数组列数
printf("j = %d\n", sizeof(a[0]) / sizeof(a[0][0]));
//求二维数组行*列总数
printf("n = %d\n", sizeof(a) / sizeof(a[0][0]));
return 0;
}
数组寻址
数组参数
[EBP + 8h]
0x00EFFBEC 01 00 00 00 ....
0x00EFFBF0 02 00 00 00 ....
0x00EFFBF4 03 00 00 00 ....
0x00EFFBF8 04 00 00 00 ....
0x00EFFBFC 05 00 00 00 ....
Arr[0] = 1
00A64721 mov eax,4
00A64726 imul ecx,eax,0
00A64729 mov edx,dword ptr [ebp+8]
00A6472C mov dword ptr [edx+ecx],1
Arr[1] = 2
00A64733 mov eax,4
00A64738 shl eax,0
00A6473B mov ecx,dword ptr [ebp+8]
00A6473E mov dword ptr [ecx+eax],2
Arr[2] = 3
00A64745 mov eax,4
00A6474A shl eax,1
00A6474C mov ecx,dword ptr [ebp+8]
00A6474F mov dword ptr [ecx+eax],3
数据溢出
#include
#include
int main()
{
int i = 0;
int Arr[5] = { 0 };
for (i = 0; i < 8; i++)
{
printf("0xCC %d \r\n", i);
Arr[i] = 0;
}
return 0;
}
字符与字符串
字符
字符串
使用char类型数组表示字符串
#include
#include
int main()
{
char Arr[] = { 'H','e','l','l','o' };
for (size_t i = 0; i < 5; i++)
{
printf("%c", Arr[i]);
}
return 0;
}
#include
#include
int main()
{
char Arr[] = { 'H','e','l','l','o', '\0'/*结束标记*/};
printf("%s \r\n", Arr);
return 0;
}
字符串
scanf通过数组变量接收字符串数据时不需要增加&
#include
#include
#include
int main()
{
//字符串
char szBuffer1[] = { 'H','e','l','l','o',0 };
printf("%s \r\n", szBuffer1);
char szBuffer2[] = "Hello 0xCC"/*字符串常量*/;
printf("%s \r\n", szBuffer2);
//字符串大小
printf("size of str -> %d \r\n", sizeof(szBuffer2));
//字符串长度
printf("strlen -> %d \r\n", strlen(szBuffer2));
//字符串输入
char szBuffer[0x256] = { 0 };
printf("whats your name -> ");
scanf_s("%s", szBuffer, 0x256);
printf("name -> %s", szBuffer);
return 0;
}
字符串处理函数
strlen
#define _CRT_SECURE_NO_WARINGS
#include
#include
#include
int main()
{
char szBuffer1[] = "Hello";
char szBuffer2[] = "0xCC";
//strlen -> 获取字符串长度
printf("%d %d \r\n", strlen(szBuffer1), strlen(szBuffer2));
return 0;
}
strcpy
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
int main()
{
char szBuffer1[] = "Hello";
char szBuffer2[] = "0xCC";
//strcpy -> 字符串拷贝
strcpy(szBuffer1, szBuffer2);
printf("%s \r\n", szBuffer1);
return 0;
}
strcat
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
int main()
{
char szBuffer1[0x256] = "Hello";
char szBuffer2[] = "0xCC";
//strcat -> 字符串拼接
strcat(szBuffer1, szBuffer2);
return 0;
}
strcmp
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
int main()
{
char szBuffer1[] = "0xccc";
char szBuffer2[] = "Hello";
//strcmp -> 字符串比较 -> equal(0)
int nEqual = strcmp(szBuffer1, szBuffer2);
printf("%d \r\n", nEqual);
return 0;
}