一组类型相同的数据【C 数组】总结

简介: 一组类型相同的数据【C 数组】总结

6e3a6c8fea6241089cbd833bc73c254c.jpg

1.什么是数组?


  数组是一组相同数据的集合

2.一维数组初始化


前面我们学习了如何定义一个变量,其中变量是这么定义的 :

int a;  //int 数据类型  //变量名

那数组是如何定义的呢? 让我们看下面的代码

int arr[5]={0,1,2,3,4}; //int 数据类型 arr 数组名 //[5]代表里面有五个元素

所以这是一个包含有5个元素的int类型数组;    

数组的初始化:

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)


但是对于下面的代码要区分,内存中如何分配。

1. char arr1[] = "abc";
2. char arr2[3] = {'a','b','c'};


对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。 我们来看代码:

# include <stdio.h>
int main (void)
{
  int arr[5]={0,1,2,3,4};//数组的完全初始化
}


总结:

  1. 1.数组是使用下标来访问的,下标是从0开始。
  2. 2. 数组的大小可以通过计算得到。
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);


 2.1 一维数组遍历


数组是可以通过下标的方式来遍历,上面已经介绍过了数组的初始化,我们来尝试一下写写代码。

for(int i = 0;i<5;i++)
  {
    printf("%d ",arr[i]);//依次访问0-4的所有数组元素
  }
  return 0;

于是这就是数组的一个简单的遍历。


补充:


数组的下标是有范围限制的。 数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。 所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。 C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的, 所以程序员写代码时,最好自己做越界的检查。

#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]);//当i等于10的时候,越界访问了
   }
 return 0;
}

二维数组的行和列也可能存在越界。


2.2 冒泡排序


冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。


作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来


说并没有什么太大作用。


1. 算法步骤


比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。


2. 动图演示


61a48e6925015f90280de5e9e90176c7.gif


 2.3 代码

#include <stdio.h>
int main() {
  int a, b, temp;
  int m[10];
  for (a = 0; a < 10; a++) {
    scanf("%d", &m[a]);
  }
  for (a = 0; a < 9; a++) {
    for (b = a + 1; b < 10; b++) {
      if (m[a] > m[a + 1]) {
        temp = a[m];
        a[m] = a[m + 1];
        a[m + 1] = temp;
      }
    }
  }
  for (a = 0; a < 10; a++) {
    printf("%d ", m[a]);
  }
  return 0;
}


3.二维数组

二维数组只是比一维数组多一个维度,可以理解为矩阵。


1e8a7eac760247fdace9522e38189792.png


3.1 二维数组的创建和初始化


创建:

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

初始化:

int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略


3.2 二维数组的遍历


define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main(void)
{
  int arr[3][4] = { {2, 7, 8, 5}, 
            {75, 8, 9, 8}, 
            {26, 37, 99, 9} };
  for (size_t i = 0; i < 3; i++)    //行
  {
    for (size_t j = 0; j < 4; j++)  //列
    {
      printf("%d ", arr[i][j]*2);
    }
    printf("\n");
  }


4.数组作为函数元素传参

往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法 思想)函数 将一个整形数组排序。

错误的冒泡排序:

#include<stdio.h>
void sort(int arr[]);
int main()
{
   int i = 0;
  int rtr[10]={0};
   for(i = 0;i<10;i++)
   {
     scanf("%d",&rtr[i]);
   }
   sort(rtr);
   for(i = 0;i<10;i++)
   {
     printf("%d ",rtr[i]);
   }
  return 0;
}
void sort(int arr[])
{
   int sz = sizeof(arr)/sizeof(arr[0]);
    int i,j = 0;
    for(i = 0;i<sz;i++)
    {
      for(j = 0;j<sz-1-i;j++)
      {
        if(arr[j]>arr[j+1])
        {
          int temp = arr[j];
          arr[j]=arr[j+1];
          temp = arr[j];
        }
      }
    }
}


难道数组作为函数参数的时候,不是把整个数组的传递过去?

正确的冒泡排序:

#include<stdio.h>
void sort(int arr[],int sz);
int main()
{
   int i = 0;
  int rtr[10]={0};
   int sz = sizeof(rtr)/sizeof(rtr[0]);
   for(i = 0;i<sz;i++)
   {
     scanf("%d",&rtr[i]);
   }
   sort(rtr,sz);
   for(i = 0;i<sz;i++)
   {
     printf("%d ",rtr[i]);
   }
  return 0;
}
void sort(int arr[],int sz)
{
    int i,j = 0;
    for(i = 0;i<sz;i++)
    {
      for(j = 0;j<sz-1-i;j++)
      {
        if(arr[j]>arr[j+1])
        {
          int temp = arr[j];
          arr[j]=arr[j+1];
          temp = arr[j];
        }
      }
    }
}


数组名是什么?

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


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

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


为什么输出的结果是:40?

  1. 补充: 1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数 组。
  2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。 除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。


5.c99标准的变长数组(补充)

 这样的代码会报错吗?

#include<stdio.h>
int main()
{
    int n = 5;
   int arr[n];
}


答案是在C99标准下,并不会;但如果在msvc里面则使用会提示你要使用变量而不是常量。这就是C99标准。

相关文章
|
7月前
|
数据处理
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
72 0
|
2月前
字典,列表和字符串之间的转化示例
【10月更文挑战第13天】 字典,列表和字符串之间的转化示例
48 0
|
7月前
2020-10-10 数组和对象的区分方法
2020-10-10 数组和对象的区分方法
数组与集合的转换
数组与集合的转换
61 0
|
7月前
|
索引 Python
列表、元组和字典之间的区别是什么
列表、元组和字典之间的区别是什么
88 0
|
7月前
|
C++
stl判断数据的类型
stl判断数据的类型
|
存储 索引
数组与字符串的关系【了解一下】
数组与字符串的关系【了解一下】
132 0
比较任意类型是否相等!
比较任意类型是否相等!
85 0
判断某个值是否在多维关联数组中 返回该值的所在的关联数组
判断某个值是否在多维关联数组中 返回该值的所在的关联数组
90 0