0
点赞
收藏
分享

微信扫一扫

初始数组+冒泡排序

何以至千里 2022-03-12 阅读 168

数组的定义:一组相同类型元素的集合

数组的下标

C 语言规定:数组的每个元素都有一个下标,下标是从 0 开始的。

数组可以通过下标来访问的。

数组的使用

int n = 10;

scanf(“%d”,&n);

int arr[n] 当创建数组时,在VS2019编译器中,不支持C99变量数组。在Linux-centos编译器里可以实现。

注:C99中引入了变长数组的概念,允许数组的大小用变量来指定。部分编译器不支持

数组的创建

type_t   arr_name   [ const_n ];    //type_t 是指数组的元素类型

                                                   //const_n 是一个常量表达式,用来指定数组的大小

int         arr              [10];

数组未初始化输出的时候,计算机输出的是一些“随机值”。当在全局变量,静态变量static未初始化的时候。输出的值是0。

 本质上是因为这些变量或者数组所处的区域不同。

字符数组的创建

char arr1[] = "abc"(字符串初始化数组)   里面为 a b c  \0 该数组有4个字符

char arr2[] = {'a'  ,   'b'   ,  'c'  } 里面只有abc3个字符
char arr1[5] = 'abc';
char arr2[5] = {'a' ,'b' ,'c' };

arr1中前四个是初始化的,最后一个\0是计算机填充的。

arr2中前三个是初始化的,最后两个\0是计算机填充的, 


一维数组的使用

[]   下标引用操作符。它其实就数组访问的操作符。

arr[4].  arr 和 4是[]两个操作数

 sizeof(arr)用来计算整个数组的大小,400个字节

sizeof(arr[0])计算数组第一个元素的大小,4个字节

一维数组在内存中的存储

%p打印地址(16进制),每个地址差4(每个元素是4个字节),所以数组是连续存放的(包括二维数组) 。随着数组下标的增长,地址由低到高变化。

这里用指针的方式访问数组 p+1跳4个字节

二维数组的使用

二维数组如果有初始化,行可以省略,列不能省略

int arr [][] = {0}  这里是将第一行第一列的元素初始化为0,剩余的是电脑上分配的0,所以全是0

#include <stdio.h>
int main()
{
 int arr[3][4] = {{1,2},{4,5},{5,6}};
 int i = 0;
 for(i=0; i<3; i++)
 {
 int j = 0;
 for(j=0; j<4; j++)
 {

 printf("%d ", arr[i][j]);
 }
printf(“\n”);
 }
 return 0; 
}

输出的结果为:  1 2 0 0

                         4 5 0 0

                         5 6 0 0

sizeof(arr2)/ sizeof(arr2[0]) 整个数组的大小除以二维数组第一行数组的大小得出第一行数组的个数

二维数组的越界

数组的下标是有范围限制的。

数组的下规定是从 0 开始的,如果数组有 n 个元素,最后一个元素的下标就是 n-1

所C 语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 正确。数组的下标如果小于0 ,或者大于 n-1 ,就是数组越界访问了,超出了数组合法空间的访问。

数组名

简单来说,数组名就是数组首元素地址

 数组首元素地址(arr)(&arr[0])与整个数组的地址(&arr)只不过用数组第一个元素的地址表示,所以在计算机上显示的是一样的

这里的28是16进制的数字,换算成十进制是增加了40,也就是增加了整个数组的大小

如果数组名是首元素地址,那么:

 

int arr[10] = {0};
printf("%d\n", sizeof(arr));

为什么输出的结果是:40

补充:

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数

组。

2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。

下面来个数组经典案例——冒泡排序

将数组作为参数传个函数,下面是分析过程

 先确定循环的趟数。代码如下

#include <stdio.h>
void bubble_sort(int arr[])                 //(这里可以写作int *arr本质上是个指针)
{
 int sz = sizeof(arr)/sizeof(arr[0]);
    int i = 0;
 for(i=0; i<sz-1; i++)
   {
        int j = 0;
        for(j=0; j<sz-i-1; j++)
       {
            if(arr[j] > arr[j+1])
           {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
           }
       }
   }
}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    bubble_sort(arr);//是否可以正常排序?
    for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
   {
        printf("%d ", arr[i]);
   }
    return 0;
}

通过编译器监视功能我们发现,这里的sz的值为1(并没有达到我们想要计算元素个数的目的),进入for循环里面后,sz-1值为0并没有循环。结合上面的数组地址分析,因为int arr[]在这里本质上是个指针,所以sizeof(arr)在这里的值为4(32位编译器是4,64位编译器是8)。故我们在main函数里面求好值,再以参数的形式传进去。下面是正确的代码:

void bubble_sort(int arr[], int sz)   //参数接收数组元素个数
{
  int i = 0;
 for(i=0; i<sz-1; i++)               //确定趟数
   {
        int flag = 1 ;                //假设已经有序
        int j = 0;
        for(j=0; j<sz-i-1; j++)
       {
            if(arr[j] > arr[j+1])    //交换元素
           {
                flag = 0;
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
           }
       }
     if(flag==1)
           break;                    //如果flag还是等于1,说明已经排好序,跳出循环
   }

}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    int sz = sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr, sz);
    for(i=0; i<sz; i++)
   {
        printf("%d ", arr[i]);
   }
    return 0;

当然,如果是乱序数组也可以排列。

举报

相关推荐

0 条评论