C语言 数组

news2025/2/26 6:28:16

C语言 数组

  • 一、一维数组
    • 1. 数组的创建方式
      • 程序清单1
      • 程序清单2
    • 2. 计算数组的元素的个数
    • 3. 数组在内存中的存储方式
  • 二、二维数组
    • 1. 二维数组的创建方式
    • 2. 计算二维数组的行和列
    • 3. 二维数组在内存中的存储方式
  • 三、数组名的含义
    • 总结数组名的应用场景
    • 数组名作为函数参数

一、一维数组

1. 数组的创建方式

程序清单1

#include <stdio.h>

int main() {

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

	return 0;
}

数组 arr1 在定义时,长度给了 10,但初始化未完全。
数组 arr2 在定义时,未明确数组大小,底层根据初始化后提供默认大小。
数组 arr3 只被定义,未初始化,所以底层放的都是随机数字。

1-1

程序清单2

下面的三个数组呈现了字符数组的区别。

这里需要注意 sizeof 和 strlen 的区别,sizeof 求的是整个数组内所有元素占内存的大小( 包括 \0 ),strlen 求的是字符串长度( \0 之前 )。也就是说,前者求的是数组元素的大小,后者求的是字符串的长度。

#include <stdio.h>
#include <string.h>

int main() {

	char arr4[] = "abcd";
	char arr5[] = { 'a','b','c','d' };
	char arr6[10] = { 'a','b','c','d' };

	printf("%d %d\n", sizeof(arr4), strlen(arr4));
	return 0;
}

// 输出结果:5 4

1-2

2. 计算数组的元素的个数

在 C语言 中,sizeof 可以用来计算某个变量的所占内存的字节大小,所以利用【整个数组所占的内存大小】/ 【数组内某个元素所占的内存大小】,就能够得出数组长度。

#include <stdio.h>

int main() {

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", sizeof(arr)); // 40
	printf("%d\n", sizeof(arr[0])); // 4

	int size = sizeof(arr) / sizeof(arr[0]); // 求数组长度的方法
	printf("%d\n", size); // 10

	return 0;
}

3. 数组在内存中的存储方式

#include <stdio.h>

int main() {

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int size = sizeof(arr) / sizeof(arr[0]);

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

输出结果:

1-3

从上面的十六进制的地址来看,我们可以得出结论:

① 一维数组在内存中是连续存放的。
② 随着数组下标的增长,地址由低到高变化。
③ 地址之间的差值,即数组元素类型的大小。( 例如:数组存放的元素是整型,那么每个元素的地址之间就相差 4. )

二、二维数组

1. 二维数组的创建方式

#include <stdio.h>

int main() {

	int arr1[3][5] = { 0 };
	int arr2[3][5] = { 1,2,3,4,5,6 };
	int arr3[][5] = {1,2,3,4,5,6};
	int arr4[3][5] = { {1,2}, {3,4}, {5,6} };

	//int arr[3][] = { {1,2}, {3,4}, {5,6} }; // error
	return 0;
}

1-4

注意事项:

① 二维数组在创建时,行可以省略,但列不可省略。

② 如果提前知道二维数组中存储什么元素,推荐上面的 arr4 (直接初始化);如果提前不确定二维数组的元素,推荐上面的 arr1. (初始化第一行第一列的元素,后面的自动初始化为 0.)

2. 计算二维数组的行和列

和计算一维数组的大小思想相同,这里依旧先采用 sizeof 计算内存所占大小,之后分别计算行和列。

#include <stdio.h>

int main() {

	int arr[3][5] = { {1,2}, {3,4}, {5,6} };
	
	// 整个二维数组的大小 / 第一行一维数组大小
	int row = sizeof(arr) / sizeof(arr[0]); // 60/20 = 3

	// 第一行一维数组大小 / 第一行第一个数组元素的大小
	int column = sizeof(arr[0]) / sizeof(arr[0][0]); // 20/4 = 5

	return 0;
}

3. 二维数组在内存中的存储方式

#include <stdio.h>

int main() {

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

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

输出结果:

1-5

从上面的十六进制地址的输出结果来看,我们得出结论:

二维数组在内存中是连续存放的,也就是说实际的内存是连续存放的,和我们想象中的几行几列不一样。

1-6

三、数组名的含义

#include <stdio.h>

int main() {

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

	printf("%p\n", arr);
	printf("%p\n\n", arr + 1); // 往后跳 4 个字节

	printf("%p\n", &arr[0]);
	printf("%p\n\n", &arr[0] + 1); // 往后跳 4 个字节

	printf("%p\n", &arr);
	printf("%p\n\n", &arr + 1); // 往后跳 40个字节

	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr[0])); 
	//printf("%d", sizeof(&arr); // error
	
	return 0;
}

输出结果:

1-7

1-8

总结数组名的应用场景

从上面的四组数据来看数组名在不同的场景下,起到不同的作用.

一般情况下,数组名就是数组首元素的地址。但有两个例外:

① 【sizeof(数组名)】,数组名表示整个数组,计算的是整个数组占用内存的大小。

② 【&数组名】,数组名表示整个数组,取出的是整个数组的地址。

1-9

数组名作为函数参数

#include <stdio.h>

void test(int arr[]) {

	int size = sizeof(arr) / sizeof(arr[0]); // 1 / 1 = 1

	for (int i = 0; i < size; i++) {
		printf("%d ", arr[i]);
	}
}

int main() {

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	
	test(arr); // 传递的实际上是首元素的地址 <==> &arr[0]

	return 0;
}

输出结果:(32 位)

1-10

现在我们就能理解了,arr 这个数组名作为参数时,即表示数组首元素的地址。所以,本质上,它就相当于传了一个指针变量给 test 函数。思考过后,我们就能够将上面的程序改为下面的程序。

#include <stdio.h>

void test(int* arr, int size) {

	for (int i = 0; i < size; i++) {
		printf("%d ", arr[i]);
	}
}

int main() {

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int size = sizeof(arr) / sizeof(arr[0]);
	test(arr, size); // 传递的实际上是首元素的地址 <==> &arr[0]

	return 0;
}

// 输出结果:1 2 3 4 5 6 7 8 9 10

总结两个重要的点:

① arr 数组名作为参数时,传递的是一个指针变量。
② 计算数组的长度不能放在外置函数。

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

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

相关文章

22.11.16打卡 mysql学习笔记

马上要考试了, 越到考试越想玩, 烦躁烦躁烦躁, 没学多少, 争取明天把mysql基础篇学完 DCL介绍 2022年11月16日 14:54 DCL主要用来处理数据库有哪些用户可以访问, 每个用户具有什么样的权限 用户管理 2022年11月16日 15:20 所有用户的数据都存放在系统数据库mysql中的user表…

Python是什么?要如何学习?

Python 是荷兰人 Guido van Rossum &#xff08;吉多范罗苏姆&#xff0c;中国程序员称其为“龟叔”&#xff09;在 1990 年初开发的一种解释型编程语言。 Python 的诞生是极具戏曲性的&#xff0c;据 Guido 自述记载&#xff0c;Python 语言是在圣诞节期间为了打发无聊的时间而…

基于全景相机的视觉里程计算法研究

一、视觉里程计 视觉里程计技术首先建立相机的成像模型&#xff0c;接着通过标定算法计算相机参数&#xff0c;最后建立相邻图像的关联并估计相机运动轨迹。 1.1相机在空间中运动的描述 描述相机在三维空间中的运动状态&#xff0c;即求解相机在空间中不同时刻下的位姿关系。相…

假冒网站引发多重安全风险 | 官方严正声明:切勿在非官方渠道购买或下载 Navicat 软件

Navicat 严正声明 近期&#xff0c;有关于 Navicat 假冒网站的事件&#xff0c;不法分子通过仿制官方网站&#xff0c;诱导用户下载盗版软件。Navicat 官方已正式向国内监管部门举报&#xff0c;提请将该不法网站下架。目前&#xff0c;监管部门已介入调查中。 我司呼吁广大用…

这次,听人大教授讲讲分布式数据库的多级一致性|TDSQL 关键技术突破

近年来&#xff0c;凭借高可扩展、高可用等技术特性&#xff0c;分布式数据库正在成为金融行业数字化转型的重要支撑。分布式数据库如何在不同的金融级应用场景下&#xff0c;在确保数据一致性的前提下&#xff0c;同时保障系统的高性能和高可扩展性&#xff0c;是分布式数据库…

C语言之详解内存操作函数

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C/C】 目录前言memcpy模拟实现memmove模拟实现memcmpmemset前言 memcpy叫做内存拷贝&#xff0c;memmove叫做内存移动&#xff0c;memc…

【数据结构】模拟实现双向链表

你必须非常努力&#xff0c;才能显得毫不费劲 目录 1.模拟实现双向链表 1.1 DLinkedList的内部类 1.2 DLinkedList的成员属性 1.3 DLinkedList的成员方法 1.3.1 在链表开头插入一个新结点 1.3.2 在链表结尾插入一个新的结点 1.3.3 计算结点个数 1.3.4 在链表任意位置…

4.构造器,this,修饰符详解

构造器&#xff1a; 构造器也叫构造方法&#xff0c;无返回值。非构造方法必须要有返回类型 主要作用&#xff1a;完成对象的初始化&#xff0c;创造对象时&#xff0c;自动调用构造器初始化对象 即使没有显示地使用static关键字&#xff0c;构造器实际上也是静态方法 JAVA…

HTML---基础入门知识详解

1&#xff1a;标签的概念 在别人写的网页中我们会看到许多文字&#xff0c;图片排版整齐&#xff0c;让人看的赏心悦目&#xff0c;这就是用到了标签&#xff0c;或者说标签就是帮我们实现某种作用的工具&#xff0c;比如制作段落&#xff0c;换行&#xff0c;导入图片&#x…

Android App 导出APK安装包以及制作App图标讲解及实战(图文解释 简单易懂)

操作有问题请点赞关注收藏后评论区留言~~~ 一、导出APK安装包 之前在运行App的时候&#xff0c;都是先由数据线连接手机和电脑&#xff0c;再通过Android Studio的Run菜单把App安装到手机上&#xff0c;这种方式只能在自己手机上调试应用&#xff0c;如果想在别人手机上安装应…

Python画爱心——谁能拒绝用代码敲出会跳动的爱心呢~

还不快把这份浪漫拿走&#xff01;&#xff01;节日就快到来了&#xff0c;给Ta一个惊喜吧~ 今天给大家分享一个浪漫小技巧&#xff0c;利用Python中的 HTML 制作一个立体会动的心动小爱心 成千上百个爱心汇成一个大爱心&#xff0c;从里到外形成一个立体状&#xff0c;给人视…

FITC标记SPG,FITC-SPG,荧光素标记链球菌G蛋白

产品名称&#xff1a;FITC标记SPG&#xff0c;荧光素标记链球菌G蛋白 英文名称&#xff1a;FITC-SPG 纯度&#xff1a;98% 规格&#xff1a;1mg 5mg 10mg 产地&#xff1a;西安 说明&#xff1a;提供使用说明&#xff0c;核磁图谱&#xff0c;包装&#xff0c;价格&#xff0…

ipv6地址概述——带你了解ipv6与ipv4的不同

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.ipv4与ipv6 1.ipv4与ipv6概述 在开始Pv6的学习以前&#xf…

Tomcat的安装与Maven依赖Servlet的使用

Tomcat的安装与Maven依赖Servlet的使用&#x1f34e;一.Tomcat应用&#x1f352;1.1什么是Tomcat&#x1f352;1.2Tomcat下载安装&#x1f352;1.3 IDEA插件Smart Tomcat&#x1f34e;二.Maven依赖Servlet应用&#x1f352;2.1什么是Servlet&#x1f352;2.2创建Servlet简单实现…

《Java》图书管理系统

这是一个对于Java中知识点的类&#xff0c;抽象类&#xff0c;封装&#xff0c;继承&#xff0c;多态&#xff0c;接口等进行的一个简单的代码练习&#xff0c;对于实际的图书管理系统还需要一点的优化 目录 前言 效果展示 功能模块 书架 定义书的类 创建书架 用户 User用…

黑马点评--优惠卷秒杀

黑马点评–优惠卷秒杀 全局ID生成器&#xff1a; 是一种在分布式系统下用来生成全局唯一ID的工具&#xff0c;一般要满足下列特性&#xff1a; 为了增加ID的安全性&#xff0c;我们可以不直接使用Redis自增的数值&#xff0c;而是拼接一些其它信息&#xff1a; Redis自增ID策…

CentOS7安装MySQL8

文章目录一 前言二、Centos 7 安装 mysql8 步骤&#xff1a;1.下载MySQL官方的 Yum Repository2.安装方法一&#xff1a; 用wget 下载后安装方法二&#xff1a;下载 RMP 软件包将该软件包上传到 Linux 服务器&#xff0c;并安装。3.Navicate 远程连接配置一 前言 最近在自己的…

Python 入门基础

第一个Python程序之打印 Hello World! print("Hello World!")字符串定义的三种方式&#xff0c;type 用了检测数据类型 # 单引号定义法&#xff0c;使用单引号进行包围 name 测试 print(type(name)) # 双引号定义法 name "测试" print(type(name)) # 三…

vue3+ts组件练习(defineExpose defineEmits defineProps)

学习关键语句&#xff1a; vue3ts 组件写法 写在前面 进化到 vue3 ts 的时代&#xff0c;vue的不少语法发生了改变&#xff0c;尤其是选项式 API 变为了组合式 API 和 typescript 的使用使得从 vue2 过来的人需要尽快熟悉新的写法&#xff0c;毕竟大差不差嘛 文章最后有本文…

图像分割 - 阈值处理 - 全局阈值处理

目录 1. 介绍 2. 代码实现 3. 代码讲解 1. 介绍 当目标和背景像素的灰度分布非常不同的时候&#xff0c;可以对整个图像使用全局阈值 在大多数的应用中&#xff0c;图像之间通常存在足够的变化&#xff0c;全局阈值是一种合适的办法。所以&#xff0c;需要一种对图像做阈值…