C语言入门篇(六)

news2024/11/25 14:45:34

前言
  C 语言支持数组数据结构,数组是用来存储一系列数据,而且是一系列相同类型的变量。

数组

  • 1. 一维数组
    • 1.1 数组的创建
    • 1.2 数组的初始化
    • 1.3 数组的使用
    • 1.4 数组在内存中的存储
  • 2. 二维数组
    • 1.1 数组的创建
    • 1.2 数组的初始化
    • 1.3 数组的使用
    • 1.4 数组在内存中的存储
  • 3. 数组越界
  • 4. 数组作为函数参数
    • 4.1 数组名你用对了吗?
  • 结束语

1. 一维数组

数组是一组相同类型元素的集合。(存放一组数)

1.1 数组的创建

数组创建方式:

type_t arr_name [const_n];
//type_t    指数组的元素类型
//const_n   常量表达式,指定数组的大小

🍤数组创建实例:

int arr[9];

//不同数据类型的数组
char arr2[10];
float arr3[9];
double arr4[5];

//下面是一个错误例子:
int n=9;
int arr1[n];//[]中必须是常量表达式

🍩注:
数组创建,在C99标准之前,[ ]中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化。

1.2 数组的初始化

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

比如:

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};//完全初始化
int arr2[10] = { 1,2,3 };//不完全初始化,剩余的元素默认都是0
int arr3[10] = { 0 };//不完全初始化,剩余的元素默认都是0
int arr4[] = { 0 };//省略数组的大小,数组必须初始化,数组的大小是根据初始化的内容来确定
char arr5[]={'a','c'9};
char arr6[]="abc";
char arr7[3]={'a','b','c'};
int arr8[];//错误

🍩数组在创建的时候如果想不指定数组的确定的大小就得初始化。

🍩数组的元素个数根据初始化的内容来确定。

1.3 数组的使用

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

下图是一个长度为 10 的数组,第一个元素的索引值为 0,第九个元素的索引值为 8:
在这里插入图片描述

对数组元素进行索取:

在这里插入图片描述
🍤实例1:计算数组元素个数

#include <stdio.h>
int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};//数组的不完全初始化
	int sz = sizeof(arr) / sizeof(arr[0]);	//计算数组的元素个数
	printf("%d\n",sz);
	return 0;
}

🍩sizeof:返回一个对象或者类型所占的内存字节数

🍤实例2:输出数组元素

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };//数组的不完全初始化
	//对数组内容赋值,数组是使用下标来访问的,下标从0开始。
	int i;//做下标
	for (i = 0; i < 10; i++)//定义的数组有10个元素,所以下标是从0-9
	{
		arr[i] = i;
	}
	//输出数组的内容
	for (i = 0; i < 10; ++i)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在不知道数组长度的情况下,该如何控制for语句的循环条件?

🍤实例3:

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

🍩数组是使用下标来访问的,下标是从0开始。

🍩数组的大小可以通过计算得到。

//计算数组大小
int arr[10];
int sz = sizeof (arr)/sizeof(arr [0]);

1.4 数组在内存中的存储

我们先看一段代码:

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组大小
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);//%p -- 用来打印地址
	}

	return 0;
}

运行结果:

在这里插入图片描述
在内存中的存储地址:
在这里插入图片描述

仔细观察,可以发现后一个元素的地址比前一个元素的地址增4
说明了:数组在内存中是连续存放的,而且由高到低。

2. 二维数组

1.1 数组的创建

int arr[3][4];//3行4列
char arr[3][5];
float arr[1][3];

1.2 数组的初始化

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

🍩二维数组的行可以省略,但列不能省

比如:有二维数组

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

在这里插入图片描述

如果只知道行,无法确定(推出)数组的列数
如果知道了列,就知道了下一行从哪里开始

1.3 数组的使用

二维数组的使用也是通过下标的方式:

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

🍤实例:

#include<stdio.h>
int main()
{
	int arr[4][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7},{5,6,7,8,9} };
	int i ;//用i控制行,下标是0-3
	for (i = 0; i < 4; i++)//外循环控制行
	{
		int j ;//j控制列,下标是0-4
		for (j = 0; j < 5; j++)//内循环控制列
		{
			printf("%d ", arr[i][j]);//输出整个数组
		}
		printf("\n");//每行打印完后,换行
	}
	return 0;
}

1.4 数组在内存中的存储

像一维数组一样,这里我们尝试打印二维数组的每个元素:

#include<stdio.h>
int main()
{
	int arr[3][4] = { 0 };
	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;
}

运行结果:

在这里插入图片描述

可以发现:二维数组在内存中也是连续存储的

3. 数组越界

数组的下标是有范围限制的。
数组的下标规定是从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]);//当i等于10的时候,越界访问了
   }
 return 0;
}

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

4. 数组作为函数参数

在写代码的时候,需要将数组作为参数传给函数。

比如:实现一个冒泡排序函数将一个整形数组排序。

冒泡排序:依次比较两个相邻的元素的大小,按照升序或降序排列,重复的比较,直到所有元素排列完成。
在这里插入图片描述

代码实现:

//升序排列
void bubble_sort(int* arr, int sz)//这里的arr的本质是指针
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)//数组下标范围:0-sz-1,
	{
		int j = 0;
		int flag = 1;//假设已经是有序数组
		//进行比较
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				//交换
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
				flag = 0;
			}
		}
		if (flag == 1)
			break;
	}
}

int main()
{
	int arr[10] = { 0 };
	int i ;
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组大小
	for (i = 0; i < sz; i++)
	{
		scanf("%d", &arr[i]);//输入
	}
	//arr作为数组进行了传参
	bubble_sort(arr, sz);//arr 是数组首元素的地址,传递的是首元素的地址
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);//输出排好序的数组元素
	}
	return 0;
}

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。

所以即使在函数参数部分写成数组的形式: int arr[] ,其表示的依然是一个指针: int *arr

4.1 数组名你用对了吗?

先看一段代码:

//%p--打印地址
int main()
{
	int arr[10] = { 1,2,3};
	printf("%p\n", arr);//首元素地址--arr[0]
	printf("%p\n", arr+1);//arr[1]

	printf("%p\n", &arr[0]);//首元素取地址
	printf("%p\n", &arr[0]+1);//arr[1]

	printf("%p\n", &arr);//数组的地址,是从首元素地址开始的
	printf("%p\n", &arr+1);//数组+1,跳过整个数组

	printf("%d\n", sizeof(arr));//整个数组所占内存空间大小
	return 0;
}

运行结果:

在这里插入图片描述

🍩数组名通常情况下就是数组首元素的地址。

但是有2个例外:

🍥 sizeof(数组名),数组名单独放在sizeof()内部,这里的数组名表示整个数组,计算的是整个数组的大小

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

除此之外所有遇到的数组名都表示数组首元素的地址


结束语

合理安排时间,就等于节约时间。
  我们下一篇文章再见。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

23款奔驰GLS400升级柏林之声音响系统+HUD抬头显示系统

奔驰GLS400升级柏林之声的音响效果自然非同凡响&#xff0c;在人声、交响乐音乐厅感受方面都有非常逼真的现场感受&#xff0c;结合柏林之声的界面调整&#xff0c;可以在不同方位体验的高保真的音乐之享&#xff01; 强悍的显示效果&#xff0c;让您在动感中驾驭乐趣&#xff…

MinIO简单安装及使用

MinIO简介 MinIO是一个开源的、云原生的对象存储服务器&#xff0c;它提供了简单、高性能、安全、可扩展的存储服务。MinIO最初是作为一个Amazon S3兼容的对象存储服务器开发的&#xff0c;可以通过S3 API与其他应用程序和服务进行交互。MinIO支持分布式部署&#xff0c;可以在…

[HFCTF 2021] final web复现

我坐着什么都没做&#xff0c;因为我有太多事情要做.......&#x1f62d; (bushi) (1) tinypng(Laravel rce phar反序列化) 是一个laravel框架项目 看一下路由 <?phpuse Illuminate\Support\Facades\Route;/* |-----------------------------------------------------…

Jpa列表查询@OneToOne,@OneToMany出现多条sql(N+1)解决办法

最近用了jpa的OneToOne&#xff0c;OneToMany管理对象&#xff0c;但是在查询分页列表&#xff0c;列表的过程中触发了N1的sql查询&#xff0c;这里我用了NamedEntityGraphs去解决 实体关系 1.父实体 /*** 规则配置** author lyj* date 2023-07-06*/ Getter Setter Entity T…

计算机体系结构基础知识介绍之缓存性能的十大进阶优化之减少命中时间和流水线访问和多组缓存增加带宽(三)

优化二&#xff1a;减少命中时间的方式预测 路预测是一种高速缓存优化技术&#xff0c;它在高速缓存中保存额外的位来预测下一次高速缓存访问的路&#xff08;或者组内的块&#xff09;。这种预测可以提前设置多路选择器来选择期望的块&#xff0c;并且在那个时钟周期内&#…

ModaHub魔搭社区:ChatGLM 集成进LangChain的教程

目录 接入自己的LLM 搭建ChatGLM的api 封装ChatGLM的LLM 测试 总结 参考 最新一段时间一直在学习LangChain相关的文档&#xff0c;发现LangChain提供了非常丰富的生态&#xff0c;并且也可以让业务非常方便的封装自己的工具&#xff0c;接入到LangcChain的生态中&#xf…

Hystrix前言--什么是服务雪崩

什么是服务雪崩 这是在高并发的前提下&#xff0c;比如A、B只有100个线程&#xff0c;都在做这样一个操作&#xff0c;100个线程不能回收&#xff0c;当第101个客户来访问的时候直接报503。 服务雪崩的本质&#xff1a;线程没有及时回收。 不管是调用成功还是失败&#xff0c;只…

干货整理,Selenium 自动化测试常见异常问题 +解决方法(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 异常1&#xff1a…

SpringIoc容器之Aware | 京东云技术团队

1 前言 Aware是Spring提供的一个标记超接口&#xff0c;指示bean有资格通过回调样式的方法由Spring容器通知特定的框架对象&#xff0c;以获取到容器中特有对象的实例的方法之一。实际的方法签名由各个子接口确定&#xff0c;但通常只包含一个接受单个参数的void返回方法。 2…

【接口测试】Postman —— 接口测试知识准备

1.0 前言 ​应用程序编程接口&#xff08;Application Programming Interface, API&#xff09;是这些年来最流行的技术之一&#xff0c;强大的Web应用程序和领先的移动应用程序都离不开后端强大的API。API技术的应用给系统开发带来了便利&#xff0c;但也对测试人员提出了更高…

[JAVA数据结构]HashMap

目录 1.HashMap 1.1Map的常用方法 1.2HashMap的使用案例 1.HashMap 基于哈希表的实现的Map接口。 Map底层结构HashMap底层结构哈希桶插入/删除/查找时间复杂度O(1)是否有序无序线程安全不安全插入/删除/查找区别通过哈希函数计算哈希地址比较与覆写自定义类型需要覆写equal…

leetcode.1504. 统计全 1 子矩形(单调栈-java)

统计全 1 子矩形 leetcode.1504. 统计全 1 子矩形题目描述单调栈解题代码演示 单调栈专题 leetcode.1504. 统计全 1 子矩形 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/count-submatrices-with-all-ones 题目描述 给…

pytest之配置文件pytest.ini

前言&#xff1a; pytest.ini文件是pytest的主配置文件&#xff0c;可以改变pytest的运行方式&#xff0c;它是一个固定的文件pytest.ini文件&#xff0c;读取配置信息&#xff0c;按指定的方式去运行。 pytest.ini文件的位置一般放在项目的根目录下&#xff0c;不能随便放&a…

Vant入门介绍

Vant 介绍 Vant是有赞开源的一套基于Vue2.0的Mobile组件库。Vant 是一套轻量、可靠的移动端组件库。通过 Vant&#xff0c;可以搭建出风格统一的&#xff0c;提升开发效率。通过Vant,可以搭建出风格统一的,提升开发效率。目前已有近50个组件,这些组件被广泛使用于有赞的各个移…

LVS-DR排错思路

一.LVS-DR实验排错思路 1.案例架构图 DR服务器&#xff1a;192.168.27.11 web服务器1&#xff1a;192.168.27.12 web服务器2&#xff1a;192.168.27.13 vip&#xff1a;192.168.27.180 客户端&#xff1a;192.168.27.2 1&#xff1a;配置负载调度器&#xff1a;&#xff…

【集群】脑裂是什么?Zookeeper是如何解决的?

文章目录 什么是脑裂Zookeeper集群中的脑裂场景过半机制 什么是脑裂 脑裂(split-brain)就是“大脑分裂”&#xff0c;也就是本来一个“大脑”被拆分了两个或多个“大脑”&#xff0c;我们都知道&#xff0c;如果一个人有多个大脑&#xff0c;并且相互独立的话&#xff0c;那么…

[HDCTF2019]MFC

前言 mfc逆向&#xff0c;有一个VM壳一看到它就头疼&#xff0c;好在这道题用不到&#xff0c;可以直接通过xspy获取mfc自定义消息 分析 工具下载&#xff1a; https://bbs.kanxue.com/thread-170033.htm 开始时完全没有头绪&#xff0c;有虚拟壳&#xff0c;用ida打开也看…

AMEYA360:Panasonic松下HF系列压敏电阻器

Panasonic HF系列压敏电阻器符合AEC-Q200标准&#xff0c;最大允许额定电压为16VDC&#xff0c;钳位电压高达43A。这些紧凑型SMD压敏电阻器适合用于汽车应用&#xff0c;采用模制结构&#xff0c;因此能够耐受很强的“焊接热冲击”。这些压敏电阻器符合ISO7637-2和ISO16750-2负…

迪赛智慧数——饼图(玫瑰饼图):抑郁症发病群体年龄

效果图 痛心&#xff0c;震惊了全网&#xff0c;著名歌手李玟&#xff0c;抑郁症自杀离世&#xff01; 为什么看起来阳光开朗的人&#xff0c;也会得抑郁症&#xff1f;据数据调查显示&#xff0c;15-30岁为抑郁症的高发年纪&#xff0c;由于思想不够成熟&#xff0c;经验少&a…

QT开发技巧之QComboBox通过qss设置item高度,增加间隔

1.问题描述 QComboBox默认的下拉item间距太小&#xff0c;字挤在一起不好看&#xff0c;直接qss设置item高度但是没效果 2.解决后效果 可通过qss设置item的最小高度&#xff0c;增加间距&#xff0c;不同字体大小的combobox都能使用&#xff0c;简单方便 3.代码实现 &#xf…