首页 > 其他分享 >C语言:数组(一维数组,二维数组,数组越界,数组作为函数参量,冒泡排序)

C语言:数组(一维数组,二维数组,数组越界,数组作为函数参量,冒泡排序)

时间:2024-11-14 22:15:00浏览次数:3  
标签:初始化 arr int 冒泡排序 C语言 越界 数组名 数组

1、一维数组的创建和初始化

1.1、数组的创建

数组是相同类型元素的集合

• 数组中可以存放1个或者多个数据

• 数组中存放的数据,类型是相同的

数组的创建方式

元素类型   自定义数组名  ( 常量表达式 )
比如:
int  arr[10]
double  arr[5]
char  arr[8+5]

错误写法

int  arr[n];

在C99标准之前,数组的大小必须是常量或常变量

在C99之后,数组大小可以是变量,为了支持变长数组(可以指定数组的大小)

int n=10;
scanf("%d",&n);
int arr[n];//这种数组不能初始化,n为变量

上面的代码只能在支持C99标准的编译器(比如gcc)上运行

1.2、数组的初始化

指在创建数组的时候给数组一些合理的值

下面代码是不完全初始化,剩下的元素默认初始化为0
int  arr[10]={1,2,3};
char arr[5]={'a','b'};//里面放的是  a b 0 0 0 
char arr[5]="ab";//里面放的是  a b \n 0 0
int arr[]={1,2,3,4}//元素个数为4,默认初始化为4

1.3、一维数组的使用

下标引用操作符[ ],就是数组访问操作符

对于arr[10]={1,2,3,4,5,6,7,8,9,10},数组的大小

59365bee795b47c1ab9509b191c172c6.png

数组大小可以通过计算得到:
99438b2b7a504b56908f373c826a374c.png

sizeof是一个非常重要的操作符,用于获取变量或数据类型在内存中占据的字节大小 

1.4、一维数组在内存中的储存

数组在内存中是连续存放的

验证

include<stdio.h>
int main()
 {
     int arr[]={1,2,3,4,5,6,7,8,9,10};
     int i=0;
     int sz=sizeof(arr)/sizeof(arr[0]);
     for(i=0;i<sz;i++)
     {
         printf("&arr[%d]=%p\n",&arr[i]);//%p是打印地址符号
    }
    return 0;
 }

打印结果是

0cc622a0578f493b8bb6d2426f9e9bb3.png

观察:末尾 1C,20,24,28,2C,30,34,38,3C,40 依次相差 4 个字节

 每个整型占四个字节

在内存中:

 随着数组下标的增长,元素的地址也在有规律的递增,所以数组在内存中是连续存放的

2、二维数组的创建和初始化

二维数组是啥?用图就可以解释一清二楚

 2.1、二维数组的创建

//两个[]代表多少行,多少列
int arr[2][4]
char arr[2][3]
double arr[3][4]

2.2、二维数组的初始化

完全初始化:

行和列都是从0开始 

不完全初始化示例1:

int arr[3][4]={1,2,3,4,2,3,4,5,3,4};
//拿前四个元素作为第一行,不足的用0补
//是不完全初始化

储存的样式:

 

示例2:

int arr[3][4]={{1,2},{3,4},{5,6}};//可以分开写
//不完全初始化

 储存样式:

可以省行不能省列 

2.3、二维数组在内存中的储存

二维数组在内存中也是连续的

验证:

同样末尾都相差4个字节 

二维数组在内存中是以上图形式存放,与一维数组存放形式相同 

3、数组越界

数组下标是有范围的

一维数组越界访问:

运行结果:

 

编译器没有报错

C语言本身不做数组的越界检查的,编译器不一定报错,所以自己要做检查。

 可以通过计算数组大小来防止越界(但不能保证代码总是对的,还需要检查):

二位数数组越界:

 

打印结果:
 

 结果中前面打印,而到最后才显示越界,因为在内存中是连续的一行,越界访问[0][4]的时候,就向下一位访问,即访问到[1][0]位,每一行的每一列都越界访问,依次进行下去就会越界

 4、数组作为函数参数

4.1、冒泡排序数组核心思想

从小到大排序: 

void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
     int i = 0;
     for(i=0; i<sz-1; i++)
     {
         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);
      int i = 0;
      for(i=0; i<sz; i++)
      {
          printf("%d ", arr[i]);
      }
          return 0;
}

 方法2(优化):

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;
}
}

4.2、数组名是什么

数组名是首元素的地址

但有两个例外:

1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

除此之外,任何地方使用数组名,数组名都表示元素的地址。

arr和&arr有什么区别?

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

输出结果:

&arr[0] = 0077F820
&arr[0]+1 = 0077F824
arr = 0077F820
arr+1 = 0077F824
&arr = 0077F820&arr+1 = 0077F848

 &arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是
首元素的地址,+1就是跳过⼀个元素。但是&arr 和 &arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的。

标签:初始化,arr,int,冒泡排序,C语言,越界,数组名,数组
From: https://blog.csdn.net/Alivia_Sophia/article/details/143749654

相关文章

  • C语言中的函数(大白话理解,超详细)
    1、函数是什么?函数就是一种工具,你需要的时候就可以调用他,简化写代码的工作量每个C语言程序至少有一个函数,即主函数main()2、C语言中函数的分类2.1、库函数库函数:是预先编写好的、可供程序员直接使用的函数注意:1、使用库函数必须包括#include对应的头文件(就是""或<>里......
  • C语言期末必练题目——part 9(程序填空)
    6.下面程序的功能是在a数组中查找与x值相同的元素所在位置,请填空。   #include<stdio.h>       void main()        {inta[10],i,x;          printf(“input10integers:”);    for(i=0;i<10;i++)scanf(“%d”,......
  • 代码随想录:有序数组的平方
    代码随想录:有序数组的平方仍然是双指针,一开始也想到了双指针,不过很笨的创造了两个数组,一个负数的一个正数的,两个数组比大小后插入。但其实可以直接把原数组平方后,从左右两边插入。有两点值得注意:1.已知数组大小的情况下,可以直接倒着插入数组。2.创建vector时需要指定元素的个数......
  • 郝玩的数据结构2——树状数组(待upd)
    首先,拉张图树状数组,相对于线段树来说,空间复杂度更小,但是可以处理的信息具有局限性常用于处理区间(矩阵)查改(差分转化为单点查改),单点查改板子题1Accode:点击查看代码#include<bits/stdc++.h>#definelowbitx&-xusingnamespacestd;intn,m,s[500005];voidchange(intx......
  • Java 数组操作:反转、扩容与缩容
    在Java中,数组是一种固定长度的数据结构,一旦创建,其大小无法更改。然而,常常在实际编程中,我们需要对数组进行扩容、缩容或其他操作。本文将介绍如何通过Java实现数组反转、扩容和缩容的操作,并在代码中演示这些常见的数组操作。1.数组反转数组反转是一个常见的操作,通常用于......
  • Java常见排序算法详解:快速排序、插入排序与冒泡排序
    在程序设计中,排序是最基本的操作之一。Java提供了多种排序算法,今天我们将介绍三种常见的排序方法:快速排序、插入排序和冒泡排序。我们不仅会分析它们的基本原理,还会提供实际的代码实现,帮助大家更好地理解并应用这些排序算法。一、快速排序(QuickSort)快速排序是一种分治法的排......
  • E45.【C语言】热心网友供题:打印数字金字塔
    目录1.题目题目描述输入说明输出说明输入样例输出样例注意2.自解分析​编辑红色区域的打印橙色区域的打印绿色区域的打印蓝色区域的打印代码不用动脑筋的代码能锻炼思维的代码1.题目题目描述给出10个数,要求以金字塔形式输出,10个数按顺序摆放在金字塔中......
  • 97.【C语言】数据结构之栈
    目录栈1.基本概念2.提炼要点3.概念选择题4.栈的实现栈初始化函数入栈函数出栈函数和栈顶函数栈顶函数栈销毁函数栈基本概念参见王爽老师的《汇编语言第四版》第56和57页节选一部分1.基本概念2.提炼要点1.定义:一种特殊的线性表,其只允许在固定的一端进行......
  • 代码随想录算法训练营第一天| 704. 二分查找、35.搜索插入位置、27. 移除元素、977.有
    文档讲解:代码随想录视频讲解:代码随想录状态:完成4道题一、数组理论基础数组:连续内存空间,存储类型相同的元素集合,适合读不适合写注意:Python里可以存储不同类型的元素,但刷题时都是按照相同元素去做的相同元素占用存储的空间大小是一样的,下一个元素的位置就确定了数组时间......
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59. 螺旋矩阵 II
    文档讲解:代码随想录视频讲解:代码随想录状态:完成2道题滑动窗口滑动窗口:两个指针一前一后组成滑动窗口,并计算滑动窗口中的元素的问题适用场景:字符串匹配问题、子数组问题、定长问题滑动窗口模板:如果一个字符进入窗口,应该增加windows计数器;如果一个字符将移除窗口的......