0
点赞
收藏
分享

微信扫一扫

初学C(数组)

夏侯居坤叶叔尘 2022-01-20 阅读 62
c语言

数组是一组相同类型元素的集合。 数组的创建方式:

类型 数组名 [](数组大小,可以空着,空着的话空间就根据你后面赋值多少定。)

  举个例子

       nt arr[];

这就是创建一个数组,数组名为arr,数组类型是int。

这里必须要注意的是,数组名后括号里面不可以用变量,比如:

int count = 10;

int arr1[count];

这种是不合规范的,使用时应该尽量避免。

下面开看一下数组的使用。


#include <stdio.h>
int main()
{
 int arr[10] = {0};
 int i = 0;
 for(i=0; i<10; i++)
 {
 arr[i] = i;
 } 
 for(i=0; i<10; ++i)
 {
 printf("%d ", arr[i]);
 }
 return 0;
}

这里,我定义了一个数组,数组名是arr,有10个元素,每个元素是int型,然后我定义一个i,这里要说明一下,数组是根据下标来访问的。

比如你数组是:1 2 3 4 5 6 7 8 9 10

数组的下标是:0 1 2 3 4 5 6 7 8 9

数组的下标是从0开始,也就是说访问数组的第一个元素是找下标为0的元素。

这里for循环,arr[i],i = 0;从数组的第一个元素开始找,找下标为i的元素,并把i赋值。

这样赋值完就是0 1 2 3 4 5 6 7 8 9

之后打印出来。

数组的大小可以通过函数sizeof求,使用如下:

int sz = sizeof(arr)/sizeof(arr[0]);

用整个数组大小除以其中一个元素的大小。

数组的储存

看下面一串代码:

#include <stdio.h>
int main()
{
 int arr[10] = {0};
 int i = 0;
 for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
 {
 printf("&arr[%d] = %p\n", i, &arr[i]);
 }
 return 0;
}

结果如下:

可以看出来,数组在内存中是连续存放的 。

二维数组

我们知道char arr[]  = {0}; 可以创建一个数组,[]类是数组的元素,我们看到这样创建出来的数组就好像一条直线,想象一下这是四边形的长,我们可以不可以在[]后面再加一个[]? 就好像给它一个宽?

是可以的,类似这样的数组,我们称之为二维数组。

int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};

这里是创建的示范,注意,创建时第一个是行,第二个是列,以 arr[3][4] 举例,这里[3]可以省略,试想一下,当你有八个元素,放到4列里面,是不是一行塞不下?所以就会放到下一行去。

但如果你没有列,只有行的话,那一行可以放多少元素呢?无限放的话还要下一行干什么呢?

二维数组的储存

#include <stdio.h>
int main()
{
 int arr[3][4];
 int i = 0;
 for(i=0; i<3; i++)
 {

 int j = 0;
 for(j=0; j<4; j++)
 {
 printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);
 }
 }
 return 0;
}

 这里可以看到,二维数组跟数组一样,是连续存放的。

 

数组越界

数组的下标是有范围限制的。 数组的下规定是从0开始的,如果输入有n个元素,最后一个元素的下标就是n-1。

数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。


#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    for(i=0; i<=10; i++)
   {
        printf("%d\n", arr[i]);
   }
 return 0;
}

以这个举例子,数组10个元素,每个元素都有对应的下标,又因为第一个元素的下标是0,所以最后一个元素的下标是10-1 = 9,但我打印的时候把下标为10的元素打印出来,那这里就是越界。

数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(住1),将一串顺序错乱的整数排列成有序,我该如何实现?

#include <stdio.h>
void bubble_sort(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;
}

以这个举例,我们希望得到的是:0 1 2 3 4 5 6 7 8 9 ,但实际上,我们得到的是:

结果出乎我们意料之外,为什么结果不是我们所想的?

这里我们一步一步调试,看到下图:

 

 sz传过去了,但是为什么算出来的是1?

数组名是什么?

#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5};
 printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    return 0;
}

我们写出如上代码,看看数组第一个元素的地址,和取出数组地址对比:

可以看到两个地址是一样的,我们是不是可以理解为,数组名是首元素地址?

但如果数组名是首元素地址,那我们计算:

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

 

 为什么结果是40?

这里说两个例外:

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数 组。 2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

除此之外,数组名表示的是首元素的地址。

所以我们不应该在函数内部计算数组大小,那我们将数组大小在主函数里面算出来再传过去,结果能如我们所愿吗?

#include <stdio.h>
void bubble_sort(int arr[],int sz)
{
    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};
 int sz = sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr,sz);
    for(i=0; i<sz; i++)
   {
        printf("%d ", arr[i]);
   }
    return 0;
}

 

当然,这一次数组就有序排列了。

数组就讲到这里。

举报

相关推荐

0 条评论