【C语言】_4.数组

2023-11-19

目录

1.一维数组

2.二维数组

3.数组越界

4.数组作为函数参数


正文

1.一维数组

1.1 数组的创建 

(1)数组的概念:数组是一组相同类型元素的集合;

(2)数组的创建方式:

type_t    arr_name    [const_n] ; 

         即数组元素类型+数组+指定数组大小的常量表达式;

(3)数组的创建实例: 

char arr1[7];  
float arr2[80]; 
double arr3[15];

注:C99标准中引入了变长数组的概念,允许数组的大小用变量来指定,如果编译器不支持C99中的变长数组,则不能使用变量来表示数组大小(如常用的Vs2019不支持)

int n=0;
scanf("%d",&n);
int arr[n]={0};

 即上文代码所示定义数组的方式在Vs2019下会报错,而在Linux下可以正常运行;

1.2 数组的初始化

(1)数组初始化的概念:在创建数组的同时给数组的内容一些合理的初始值;

(2)数组初始化的实例:

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

   //不完全初始化,其余元素(arr[4]至arr[9])默认初始化为0; 

 char ch[ ]={'a','b','c'};      
   
   //也可将字符元素表示为其ASCII码值,如char ch[ ]={'a',98,'c'};

 int arr[10];                      

   //不初始化时,该数组的10个元素均为随机值;

注:(1)变长数组不支持初始化:

int n=10;
int arr[n]={0};

  在支持变长数组运行的编译环境下,变长数组不能初始化,即上文代码不可运行;

(2)数组的大小与初始化:

//1
int arr1[10]={1,2,3,4};
//2
int arr2[ ]={1,2,3,4};

区分以上两个代码:

第一个代码表示前四个元素分别初始化为1,2,3,4其余元素默认初始化为0的长度为10的数组;

第二个代码表示根据初始化赋值为1,2,3,4后确定长度为4的数组;

(3)不同区域的初始化:

(4)字符数组的初始化:

① 未初始化时:

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

区分以上两个代码:

第一个代码表示元素分别为a b c \0 四个元素的字符数组(字符串隐藏一个'\0');

第二个代码表示元素分别为a b c 三个元素的字符数组;

② 初始化时:
 

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

对比以上两个代码:

两个代码均表示元素分别为a b c \0 \0 的长度为5的字符数组;

1.3 一维数组的使用

(1)[ ]是下标引用操作符,下标从0开始,即arr[10]={1,2,3,4},arr[0]=1,0和1称为[ ]的两个操作数;

(2)一维数组元素的访问:

int main()
{
	int arr1[100] = { 1,2,3,4 };
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr1[i] = i + 1;
	}                         //赋值代码
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}                         //打印代码
	return 0;
}

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

(1)

 运行上述代码后发现,每两个相邻元素的地址相差4,是因为一个整型占4个字节;

故而: 一维数组在内存中连续存放,并且随着数组下标的增加,地址由低到高变化;

(2)

 运行上述代码后发现,p+1向后跳一个元素即跳4个字节;

2.二维数组

2.1 二维数组的创建

int arr[3][5];      //表示创建一个三行五列的数组;

2.2 二维数组的初始化

(1)

//1

int arr[3][5] = { 1,2,3,4,5,6 }; 
 
//初始化情况为:
//arr[0][0]=1,arr[0][1]=2,arr[0][2]=3,arr[0][3]=4,arr[0][4]=5,arr[1][0]=6,
//其余元素均为0;

//2

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

//初始化情况为:
//arr[0][0]=,arr[0][1]=,arr[1][0]=,arr[1][1]=,arr[2][0]=,arr[2][1]=,其余元素均为0;

(2)二维数组行可以省略,列不能省略

2.3 二维数组的使用

(1)二维数组的行和列下标均从0开始;

(2)二维数组的访问:

2.4 二维数组在内存中的存储

运行上述代码后发现,二维数组在空间内存中也是连续存放的,并且是一行一行连续存放

同时这也是为什么二维数组初始化可以省略行不可以省略列的本质解释。

3.数组越界

(1)数组越界的定义:数组下标规定从0开始,若数组有n个元素,则最后一个元素的下标是n-1。

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

(2)数组越界的示例:

 4.数组作为函数参数

4.1 冒泡排序函数的错误设计

//写一个冒泡排序的函数,排序arr数组的元素
#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[] = { 9,8,7,6,5,4,3,2,1,0 };
	bubble_sort(arr);
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

进行调试监视后,发现函数部分的sz的值为1而非10,即函数体部分未进行for循环。

故而需要思考,main函数中用数组名进行数组的传输存在异议。

4.2 数组名的含义

(1)在大多数情况下,数组名等同于数组首元素地址。

(2)在两种情况下,数组名并非数组首元素地址:

a. sizeof(数组名)时,数组名不是首元素地址,而是表示整个数组,计算的是整个数组的大小

b. &(数组名)时,数组名也表示整个数组,取出的是整个数组的地址

证明:

结论第一条的证明:

根据⑦的运行结果,若此时数组名arr仍代表首元素地址,则sizeof(arr)输出结果应该是4或8,

而输出结果却是40,说明sizeof(arr)中arr表示的是整个数组,计算的是整个数组的大小;

结论第二条的证明:

(1)①②与③④两组相同,在+1后地址均增加4,说明数组名与数组首元素地址相同;

(2)而⑤⑥的情况与①②、③④不同,+1后地址增加40,说明&(arr)表示整个数组的地址;

4.3 冒泡排序函数的正确设计

在对数组名进行了一定了解后,再回到对于冒泡函数排序的设计上来。

可以发现,4.1中的程序设计在bubble_sort(arr)时,就已错误,将数组首元素地址传递给了函数。

修改后的正确的冒泡函数设计如下:

#include<stdio.h>
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(1==flag)
     {
     break;
     }
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);       //在main函数内求sz
	bubble_sort(arr,sz);                   //将sz以参数形式传入函数
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

|| 终

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C语言】_4.数组 的相关文章

随机推荐

  • Kali Linux 通过gnome-tweaks调整原生主题的字体字号

    首先我们需要确认是否安装了 gnome tweaks 因为默认kali Linux使用的是gnome桌面程序 大部分情况下是默认就有的 你只需要确认下是否安装 使用命令行确认 whereis gnome tweaks 出现下图所示就表示有
  • Sidetree - 去中心化身份管理协议

    身份 Identity 管理是区块链应用的核心元素 在一个不可信 匿名的分布计算生态中 要实现去中心化身份管理并不是一件容易的事情 Sidetree是一个基于现有区块链平台的第二层 L2s 协议 专门用于去中心化身份管理 微软最新开源的IO
  • 史上最全Android性能优化方案解析

    Android中的性能优分为以下几个方面 布局优化 网络优化 安装包优化 内存优化 卡顿优化 启动优化 一 布局优化 布局优化的本质就是减少View的层级 常见的布局优化方案如下 在LinearLayout和RelativeLayout都可
  • IP数据报的发送和转发过程

    IP数据报的发送和转发过程 源主机如何知道目的主机是否与自己在同一网络中 同一个网络中的主机可以直接通信 这属于直接交付 不同网络中的主机不能直接通信 需要路由器的中转 这属于间接交付 现假设主机C给主机F发送ip数据报 主机C将自己的IP
  • Spring Boot整合Spring Security并设置自定义登录页面

    准备工作 创建一个Spring Boot项目 注意选择Spring Boot的版本 选择3 0以下的版本 选择如下依赖 等待项目创建成功 项目创建成功之后 添加Mybatis plus的依赖
  • matlab中使用save保存文件, 文件名中有变量

    K 3 filenm K num2str K p num2str K mat save filenm
  • C#中 的泛型

    一 泛型类 1 定义一个泛型类 这个类中某些字段的类型是不确定的 这些类型可以在类构造的时候确定下来 类似于模板 class TestA
  • Ztree组件 支持全选 和反选不影响父级

    ztree ztree v3 3 5 46 main js import ztree ztree v3 js jquery ztree core js import ztree ztree v3 css zTreeStyle zTreeSt
  • Flutter开发之——动画-Lottie

    一 概述 Lottie是Aribnb开源的面向Android iOS等的高性能动画库 Flutter原生库不支持Lottie 但是可以通过第三方插件实现Lottie的动画效果 二 导入lottie flutter插件 2 1 插件地址 Lo
  • unity局域网开关机步骤二-c#-tcp

    using System using System Collections Generic using System Linq using System Text using System Net Sockets using System
  • Python基础知识(四):一文看懂列表、元组和字符串操作

    序列 序列是具有索引和切片能力的集合 列表 元组和字符串具有通过索引访问某个具体的值 或通过切片返回一段切片的能力 列表 元组 字符串都属于序列 1 列表 列表 List 是Python中非常重要的内置数据类型 列表由一系列元素组成 所有的
  • 设计模式——简单工厂模式

    简单工厂模式定义为 简单工厂模式又称为静态工厂方法模型 它属于类创建型模式 在简单工厂模式中 可以根据参数的不同返回不同类的实例 简单工厂专门定义一个类来负责创建其他类的实例 被创建的实例通常都具有共同的父类 简单工厂模式结构图 简单工厂模
  • Picture控件的加载图像的使用总结

    一 非动态显示图片 即图片先通过资源管理器载入 有一个固定ID 二 动态载入图片 即只需要在程序中指定图片的路径即可载入 为方便说明 我们已经建好一个基于对话框的工程 名为Ttest 对话框类为CTestDlg 一 vc picture控件
  • kettle抽取数据判断是否有数据

    kettle分为两种对象 一种是作业 另一种是转换 判断是否有数据 在作业中实现即可 第一步 文件 gt 新建 gt 作业 第二步 右边有主对象树和核心对象 选择核心对象 第三步 选择条件 gt 计算表中的记录数 第四步 双击此对象 计算表
  • 前端摸鱼日记(一)

    一会又要开周五的工作总结会 一天天真闲的 此处省略一万个草 上个月招来一个技术经理 文文雅雅的 是什么也不干 看起来什么都不会 每周五就假装来开个会 真他妈无语了 实在无聊 写个日志 自从创立武当山教学院 目前只有四个人 刘大目前在武当山自
  • 详解Arduino Uno开发板的引脚分配图及定义(重要且基础)

    详解Arduino Uno开发板的引脚分配图及定义 重要且基础 https www cnblogs com Bruce H21 p 11555605 html 首先开发板实物图如下 在本篇文章中 我们将详细介绍Arduino开发板的硬件电路
  • 解决vue路由跳转到同一页面的刷新问题

    问题描述 当我使用路由跳转页面时 如果页面跳转是同一个路由 传递的参数不同时 页面不刷新 如下图 待收定金和待收首款其实跳转的是同一个组件 只是他们传递的参数不同而已 当我使用路由进行跳转时 我发现第一次是可以正确跳转的 比如我当前在其他页
  • qt中获取窗口位置和大小

    窗口左上角的位置 含边框 qDebug lt lt this gt frameGeometry x lt lt this gt frameGeometry y lt lt 1 qDebug lt lt this gt x lt lt thi
  • Ubuntu系统下常用的新建、删除、拷贝文件命令

    常用新建 删除 拷贝命令 mkdir 目录名 新建一个文件夹 文件夹在Linux系统中叫做 目录 touch 文件名 新建一个空文件 rmdir 目录名 删除一个空文件夹 文件夹里有内容则不可用 rm rf 非空目录名 删除一个包含文件的文
  • 【C语言】_4.数组

    目录 1 一维数组 2 二维数组 3 数组越界 4 数组作为函数参数 正文 1 一维数组 1 1 数组的创建 1 数组的概念 数组是一组相同类型元素的集合 2 数组的创建方式 type t arr name const n 即数组元素类型