10、C99中的变长数组
在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或者如果我们初始化数据的话,是可以省略数组大小的
示例:
int arr1[20];//常量
int arr2[3+2];//常量表达式
int arr3[ ]={1,2,3};//初始化数据的话,是可以省略数组大小
这样的语法限制,使得我们创建数组的时候不够灵活,因为在创建数组的时候,给数组一个指定的大小,如果数组太大,会浪费空间,如果数组太小,则数组的空间不够用。
C99中给了一个变长数组的新特性,允许我们可以使用变量指定数组大小。
示例:
int a=0;
scanf("%d",&a);
int arr[a];
上面示例中,数组arr就是变长数组,该数组的长度取决于变量a的值,编译器没法事先确定,只有运行时才能知道a是多少。
变长数组的根本特征就是:数组长度只有运行时才能确定,所以变长数组不能初始化。它的好处是程序员不必再写程序时,随意给数组一个估计的长度,程序可以在运行时为数字分配一个符合当前预期效果的长度。
注意:
变长数组的大小是可以使用变量来指定,在程序运行的时候根据变量的大小来指定数组的元素个数,而不是说数组的大小是可变的。数组的大小一旦确定就不能再变化了。
注意:Visual Studio 2022中不支持变长数组语法
11、数组练习
(1)多个字符从两端移动,向中间汇聚
代码:
//多个字符从两端移动,向中间汇聚
#include<stdio.h>
#include<windows.h>
int main()
{
char arr[] = "welcome to c world!!!";
//确保arr2字符数组与arr数组长度相等
char arr2[] = "**************************";
//strlen函数用于求字符串中\0前的字符个数(不包含\0)(注意:字符串默认以\0结尾)
int length = strlen(arr);
int left = 0;
int right = length - 1;
while (left <= right)
{
arr2[left] = arr[left];
arr2[right] = arr[right];
printf("%s\n", arr2);
left++;
right--;
Sleep(1000);//作用是让该程序休眠1000毫秒,从而使代码的打印过程有动态的效果
//使用Sleep函数要包含头文件:windows.h
}
return 0;
}
结果:

还可以对上述代码进行优化:每打印一条信息,就清除掉屏幕上的信息(用使用system("cls"),使用system函数时,要包含头文件:stdlib.h)
优化后的代码:
//多个字符从两端移动,向中间汇聚-优化:每打印一条信息,就清除掉屏幕上的信息
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
int main()
{
char arr[] = "welcome to c world!!!";
//确保arr2字符数组与arr数组长度相等
char arr2[] = "**************************";
//strlen函数用于求字符串中\0前的字符个数(不包含\0)(注意:字符串默认以\0结尾)
int length = strlen(arr);
int left = 0;
int right = length - 1;
while (left <= right)
{
arr2[left] = arr[left];
arr2[right] = arr[right];
printf("%s\n", arr2);
left++;
right--;
Sleep(1000);//作用是让该程序休眠1000毫秒,从而使代码的打印过程有动态的效果
//使用Sleep函数要包含头文件:windows.h
system("cls");
}
printf("%s", arr2);
return 0;
}
效果截图:

(2)二分查找
在一个升序或者降序的数组中查找一个元素,我们首先想到的是遍历数组中的元素,但这种方法往往效率比较低。
此时我们可以使用二分查找,二分查找又叫折半查找。
注意:二分查找的使用前提是数组中的元素是有序的(即:升序或降序)
折半查找的思想就是:每次都折半查找数组中的数据,如果大于/小于该区间的中间值则把查找的区间缩小一半,以此类推,最差的情况是查询的区间就只有一个元素。
代码:
//二分查找
#include<stdio.h>
int main()
{
int arr[] = { 2,4,5,6,8,10,15 };
int left = 0;//区间的左端点
int right = sizeof(arr) / sizeof(arr[0]) - 1;
int key = 0;
int mid = 0;
int flag = 0;//用于标志是否查到了数据
printf("请输入要查找的数字:");
scanf("%d", &key);
while (left <= right)
{
mid = (left + right) / 2;
if (key > arr[mid])
{
left = mid + 1;
}
else if (key == arr[mid])
{
flag = 1;
break;
}
else {
right = mid - 1;
}
}
if (flag == 0)
{
printf("没有找到");
}
else
{
printf("找到了,下标为:%d\n", mid);
}
return 0;
}
示例结果:



被折叠的 条评论
为什么被折叠?



