首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >C语言数组

C语言数组

作者头像
风中的云彩
发布于 2024-11-07 21:43:57
发布于 2024-11-07 21:43:57
1.9K0
举报
文章被收录于专栏:C/C++的自学之路C/C++的自学之路

等待太久得来的东西,多半已经不是当初自己想要的样子了。

数组的理解

1. 数组是⼀组相同类型元素的集合。 2. 数组中存放的是一个或者多个数据,但是数组元素个数不能为0。 3. 数组中存放的多个数据,它们的类型是相同的。

一维数组 

一维数组的创建并初始化 

1. 创建一维数组的同时,最好给数组初始化,否则数组内将存放任意值。 2. 数组初始化分为两种:完全初始化和不完全初始化。

代码语言:javascript
复制
type arr_name[常量值]; 

//type 指定的是数组中存放数据的类型
//arr_name 指的是数组名的名字
//[] 中的常量值是⽤来指定数组的⼤⼩的

//完全初始化
int arr[5] = {1,2,3,4,5};

//不完全初始化
int arr2[6] = {1};//1,0,0,0,0,0

 字符数组初始化

1. 字符数组是一种特殊的一维数组。 2. 只存在字符数组,而没有字符串数组。 3. 字符数组的初始化有三种情况,其中前两种都默认在字符串后面有 '\0' 元素。 4. 第一、二种情况下,是不能改变数组中的元素的。

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "hello world";//第一种
	char arr2[] = { "hello world" };//第二种
	char arr3[] = { 'h','e','l','l','o','\0'};//第三种
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	return 0;
}
//三种字符数组初始化等价

 一维数组的类型

代码语言:javascript
复制
int arr1[10];
int arr2[12];
char ch[5];

//arr1数组的类型是 int [10]
//arr2数组的类型是 int [12]
//ch 数组的类型是 char [5]

一维数组的元素个数 

1. 数组在内存中是连续存放的。 2. 我们一般用 sizeof() 操作符,分别计算出数组的长度和一个数组元素的长度,两者相除就是数组中元素的个数。

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	printf("%d\n", sizeof(arr));//计算整个数组的字节大小
	printf("%d\n", sizeof(arr[1]));//计算数组中的一个成员的字节大小
    int sz=sizeof(arr)/sizeof(arr[1]);//计算数组中成员的个数
	return 0;
}

 二维数组

 二维数组的创建并初始化

1. 和一维数组类似,创建二维数组的同时,最好给数组初始化,否则数组内将存放任意值。

代码语言:javascript
复制
type arr_name[常量值1][常量值2];

//type 指定的是数组中存放数据的类型
//arr_name 指的是数组名的名字
//[][] 中的常量值是⽤来指定数组的⼤⼩

//完全初始化
int arr[2][2] = { 0,1,2,3 };

//不完全初始化
int arr[2][2] = { 0 };

 双层循环控制二维数组

1. 在对二维数组中某个元素选中的时候,需要分步进行理解。  2. 例如 arr[i][j] ,相当于先运算 arr[i] ,选中第(i+1)行,再运算 arr[i][j] ,选中第(i+1)行的第(j+1)列。

代码语言:javascript
复制
#include <stdio.h>
int main()
{
 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
 int i = 0;
 //输⼊
 for(i=0; i<3; i++) //产⽣⾏号
 {
     int j = 0;
     for(j=0; j<5; j++) //产⽣列号
     {
         scanf("%d", &arr[i][j]); //数组名就是数组第一个元素的地址,scanf()可以不用&符号。
     }
 }
 //输出
 for(i=0; i<3; i++) //产⽣⾏号
 {
     int j = 0;
     for(j=0; j<5; j++) //产⽣列号
     {
         printf("%d ", arr[i][j]); //输出数据
     }
     printf("\n");
 }
 return 0;
}

数组与指针 

数组名的本质

1. 数组名实际上是数组首元素的地址。  2. 但是有两点例外:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2.  &(数组名),这里的数组名也表示整个数组,取出整个数组的地址。
代码语言:javascript
复制
int main()
{
 
	int arr1[] = { 1,2,3,4,5 };
	printf("%p\n", &arr1[0]);
	printf("%p\n", arr1);
}
//都是传入数组首元素地址
代码语言:javascript
复制
例子1:
int main()
{
	int arr1[] = { 1,2 };
	printf("%p\n", &arr1[0] + 1);//跳过了一个字节(1个元素)
	printf("%p\n", arr1 + 1);//跳过了一个字节(1个元素)
	printf("%p\n", &arr1 + 1);//跳过了两个字节(整个数组)
}
 
例子2:
#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);//跳过了四个字节(1个元素)
	printf("arr = %p\n", arr);
	printf("arr+1 = %p\n", arr + 1);//跳过了四个字节(1个元素)
	printf("&arr = %p\n", &arr);
	printf("&arr+1 = %p\n", &arr + 1);//跳过了四十个字节(10个元素)
	return 0;
}

一维数组传参的本质  

1. 数组传参,本质上是传址调用,传递的是数组首元素的地址。 2. 形式参数可以写成数组形式,也可以写成指针形式。  3. 指针可以理解为一个动态数组,通过动态内存管理来扩容,这时候就可以把指针名称看成数组名称,把指针名当数组名一样使用。

代码语言:javascript
复制
void test(int arr[10])//参数写成数组形式,本质上还是指针
void test(int* pa)//参数写成指针形式

//使用指针访问数组 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int arr[9] = { 0 };
	int * pa = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素个数
	for (int i = 0; i < sz; i++)
	{
		scanf("%d", pa+i);//不需要括号,这里是指针与整数的运算
	}
	for (int i = 0; i < sz; i++)
	{
		printf("%d\n", *(pa+i));//不需要括号,这里是指针与整数的运算
	}
	return 0;
}
代码语言:javascript
复制
typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;//可以理解为一个指针,也可以理解为一个动态数组。
	int capacity;//栈的空间大小
	int top;//栈顶
}Stack;
//arr直接当数组名用
ps->arr[ps->top] = 1;

指针数组 

1. 整型数组,是存放整型的数组;字符数组,是存放字符的数组;指针数组,就是一种存放指针的数组 。 2. 可以利用数组指针实现二维数组的功能。 3. 例如 arr[i][j] ,相当于先运算 arr[i] ,选中第(i+1)行,再运算 arr[i][j] ,选中第(i+1)行的第(j+1)列。

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int* arr[3] = { arr1,arr2,arr3 };//存放指针(地址)的数组
	for (int i = 0; i < 3; i++)
	{
	
		for (int j = 0; j < 5; j++)
		{
			printf("%d", arr[i][j]);//注意arr[i][j]是从前往后运算的,先算arr[i],再算arri[j].
		}
		printf("\n");
	}
	return 0;
}

致谢

感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 数组的理解
  • 一维数组 
    • 一维数组的创建并初始化 
    •  字符数组初始化
    •  一维数组的类型
    • 一维数组的元素个数 
  •  二维数组
    •  二维数组的创建并初始化
    •  双层循环控制二维数组
  • 数组与指针 
    • 数组名的本质
    • 一维数组传参的本质  
    • 指针数组 
  • 致谢
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档