一维数组名称含义:
1.除了两种特殊情况,一维数组名称都是指向数组首元素地址的指针。
特殊情况1:对数组的名称进行sizeof:计算的是整个数组的大小。
void test()
{
int arr[5] = {1,2,3,4,5};
//对一维数组名称进行sizeof();
printf("sizeof(arr) = %d\n",sizeof(arr));
}
输出结果:为整个数组的大小
特殊情况2:对数组名称取地址。
void test()
{
int arr[5] = {1,2,3,4,5};
printf("%d\n",&arr);//对数组名称取地址
printf("%d\n",&arr+1);
}
输出结果:对数组名取地址步长相当于整个数组的长度。
2.数组名称,为一个指针常量:指针的指向不可以修改。
int* p = arr;
arr = NULL;//不可以修改指向
//编译器会报错,数组名称为指针常量,指针指向不可以修改。
3.如果将数组名传入到函数参数中,为提高可读性经常写为int arr[]等价int * arr。
void printArray(int arr[],int len)//int arr[]等价int* arr;
{
for (int i=0; i<len; i++)
{
printf("%d\n",arr[i]);//arr[i]等价*(arr+i)
}
}
void test()
{
int arr[5] = {1,2,3,4,5};
int* p = arr;
int len = sizeof(arr)/sizeof(int);
printArray(arr,len);
}
输出结果:打印成功
4.访问数组元素时,下标可以为负数
void test()
{
int arr[5] = {1,2,3,4,5};
int* p = arr;
p = p+3;
printf("%d\n",p[-1]);//本质:*(p-1)
}
输出结果:因为指针移动了3,p[0]即4,p[-1]即3;
数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。
如何创建数组指针呢?
方式1:先定义出数组的类型,再通过类型创建数组指针来操纵数据。
void test()
{
int arr[5] = {1,2,3,4,5};
typedef int(ARRAY_TYPE)[5];//ARRAY_TYPE是一个数据类型,代表有5个int类型元素的数组
ARRAY_TYPE *arrP = &arr;//创建了一个指向数组的指针
//*arrP等价于arr
for (int i=0; i<5; i++)
{
printf("%d\n",(*arrP)[i]);//操纵里面数据
}
}
输出结果:操纵成功。
方式2:先定义数组指针的类型,再创建数组指针变量。
//先定义数组指针的类型,再创建数组指针变量
void test()
{
int arr[5] = {1,2,3,4,5};
typedef int(*ARRAY_TYPE)[5];//数组指针
ARRAY_TYPE arrP = &arr;
}
方式3:直接创建数组指针变量(最好用)
void test()
{
int arr[5] = {1,2,3,4,5};
int (*pArr)[5] = &arr;//直接创建数组指针
}
二维数组定义方式: 三种都是定义了同一个二维数组。
void test()
{
int arr[3][3] =
{
{1,2,3},
{4,5,6},
{7,8,9}
};//方式一,可读性高
int arr[3][3] = {1,2,3,4,5,6,7,8,9};//方式二
int arr[][3] = {1,2,3,4,5,6,7,8,9};//方式三
}
1.二维数组名称含义:指向第一个一维数组的指针。
int arr[3][3] =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
int(*p)[3] = arr;//二维数组名称指向第一个一维数组的指针
除了下面两种特殊情况:
特殊情况1:sizeof统计的为整个二维数组的长度
void test()
{
int arr[3][3] =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
int(*p)[3] = arr;//二维数组名称指向第一个一维数组的指针
printf("%d\n",sizeof(arr));//统计的为整个二维数组的长度。
}
输出结果:
特殊情况2:对数组名称取地址。
int (*p2)[3][3] = &arr;//对数组名取地址,二维数组指针变量
2.如何访问二维数组。
例如:访问其中的6,从第0行0列算起。
void test()
{
int arr[3][3] =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
printf("%d\n",arr[1][2]);//访问其中的6,从第0行0列算起,人识别
printf("%d\n",*(*(arr+1)+2));//访问其中的6,机器识别
}
访问成功:
3.二维数组做函数参数。
void printArray(int(*p)[3],int row,int col)//int p[3][3]也可以
{
for (int i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
printf("%d ",p[i][j]);
//printf("%d ",*(*(p+i)+j));也可以打印出来
}
printf("\n");
}
}
void test()
{
int arr[3][3] =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
printArray(arr,3,3);
}
如何将一串数字从小到大排序呢?我们这里可以使用选择排序。
选择排序: 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
代码实现:
void SelectSort1(int arr[],int len)//选择排序,升序
{
for (int i=0; i<len; i++)
{
int min = i;//定义出最小值下标
for (int j=i+1; j<len; j++)
{
if (arr[min] > arr[j])
{
min = j;//更新真实最小值下标
}
}
if (min != i)
{
int temp = arr[i];//交换数据
arr[i] = arr[min];
arr[min] = temp;
}
}
}
void printArray(int arr[],int len)
{
printf("排序后的数为:");
for (int i=0; i<len; i++)
{
printf("%d ",arr[i]);
}
}
void test()
{
int arr[] = {3,2,5,1,4};
int len = sizeof(arr)/sizeof(int);
SelectSort1(arr,len);
printArray(arr,len);
}
输出结果:升序排序成功。
实例1:对字符串从大到小进行排序: 和上面思路基本一致,只是传参时换为二级指针就好了,改成降序排序;这里是字符串进行比较需要用到strcmp();
实现代码:
//通过选择排序算法排序后,实现对指针数组的降序排序
void SelectSort(char** pArr,int len)
{
for (int i=0; i<len; i++)
{
int max = i;//设定最大值下标为i
for (int j=i+1; j<len; j++)
{
if (strcmp(pArr[max],pArr[j]) < 0)
{
max = j;//更新最大值小标
}
}
if (i != max)
{
char* temp = pArr[max];//交换i和max下标的元素
pArr[max] = pArr[i];
pArr[i] = temp;
}
}
}
void printArray(char** pArr,int len)
{
printf("排序后的数为:");
for (int i=0; i<len; i++)
{
printf("%s ",pArr[i]);
}
printf("\n");
}
void test()
{
char* pArr[] = {"aaa","bbb","fff","ddd","eee","ccc"};
int len = sizeof(pArr)/sizeof(char*);
SelectSort(pArr,len);
printArray(pArr,len);
}
打印结果:降序排序成功。