前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何深入掌握C语言数组(详解)

如何深入掌握C语言数组(详解)

作者头像
用户9645905
发布2022-11-30 08:06:12
9950
发布2022-11-30 08:06:12
举报
文章被收录于专栏:Linux学习~

目录

1. 一维数组

1.1 创建

1.2 初始化

1.3 使用

1.4 存储

 2. 二维数组

2.1 创建

2.2 初始化

2.3 使用

2.4 存储

3. 数组越界

4. 数组作为函数参数

4.1 冒泡排序函数

错误设计

正确设计

5.数组名



1. 一维数组

数组是构造数据类型之一

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

  • 数组: 有序数据的集合,用数组名标识
  • 元素: 属同一数据类型,用数组名和下标确定

1.1 创建

数组的创建方式:

代码语言:javascript
复制
type_t   arr_name   [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

数组创建的实例:

代码语言:javascript
复制
//代码1
int arr1[10];
//代码2
int count = 10;
int arr2[count];//数组时候可以正常创建?
//代码3
char arr3[10];
float arr4[1];
double arr5[20];

注:

1、数组必须 先定义,后使用 2、只能逐个引用数组元素,不能一次引用整个数组 3、数组元素表示形式:  数组名[下标]  , 下标可以是常量或整型表达式

4 、 数组创建, [] 中要给一个 常量 才可以,不能使用变量

1.2 初始化

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

代码语言:javascript
复制
int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {'a',98, 'c'};
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";

注:

1、数组不初始化,其元素值为 随机数

2、当全部数组元素赋初值时,可不指定数组长度

注意区分下面两个代码(内存中如何分配)

代码语言:javascript
复制
char arr1[] = "abc";\\结尾是'\0',占据内存空间是4个字节,数组长度是4个字节
char arr2[3] = {'a','b','c'};\\结尾是随机知道遇到'\0',占据内存大于3个字节,数组长度是3个字节

1.3 使用

操作符  [] : 下标引用操作符,它其实就数组访问的操作符

代码语言:javascript
复制
#include <stdio.h>
int main()
{
 int arr[10] = {0};//数组的不完全初始化
    //计算数组的元素个数
    int sz = sizeof(arr)/sizeof(arr[0]);
 //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
 int i = 0;//做下标
 for(i=0; i<10; i++)
 {
 arr[i] = i;
 } 
 //输出数组的内容
 for(i=0; i<10; ++i)
 {
 printf("%d ", arr[i]);
 }
 return 0;
 }

总结 :

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

2. 数组的大小可以通过计算得到

代码语言:javascript
复制
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);

1.4 存储

代码语言:javascript
复制
#include <stdio.h>
int main()
{
 int arr[10] = {0};
 int i = 0;
 for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
 {
 printf("&arr[%d] = %p\n", i, &arr[i]);
 }
 return 0;
 }

随着数组下标的增长,元素的地址,也在有规律的递增

得出结论: 数组在内存中是连续存放的

2. 二维数组

2.1 创建

代码语言:javascript
复制
//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

注意: 第一个[]操作符可以不填数字,但第二个一定要填

可以想象成第一个相当于是数组的行数,第二个则是数组的列数 而二维数组的存储也是连续的,可以理解成: 没有列数那么下一行又改怎么与上一行连着存储(改放在哪个位置呢?)

2.2 初始化

代码语言:javascript
复制
//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};

2.3 使用

同一维数组一样也是通过下标的方式

2.4 存储

代码语言:javascript
复制
#include <stdio.h>
int main()
{
 int arr[3][4];
 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 ,就是数组越界访问了,超出了数组合法空间的访问

小于零时存放的内容猜测是数组的元素个数?

而C 语言本身是不做数组下标的越界检查,编译器也不一定报错

所以写代码时,最好自己做越界的检查

代码语言:javascript
复制
#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. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数

比如:实现一个冒泡排序

4.1 冒泡排序函数

错误设计

代码语言:javascript
复制
//方法1:
#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[] = {3,1,7,5,8,9,0,2,4,6};
   bubble_sort(arr);//是否可以正常排序?
   for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
  {
       printf("%d ", arr[i]);
  }
   return 0;
}

方法1是有 问题的:调试之后可以看到 bubble_sort 函数内部的 sz ,是 1

注意:

数组作为参数传递时,是会被降维的,传过去的其实是数组首元素的地址(相当于指针)

而在方法一在另一个函数内进行计算数组大小是没有意义的

并不能将整个数组给传递过去的,但可以依靠地址对数组进行访问

毕竟空间位置已经知道了

正确设计

代码语言:javascript
复制
//方法2
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
 //代码同上面函数
}
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);//是否可以正常排序?
    for(i=0; i<sz; i++)
    {
      printf("%d ", arr[i]);
    }
 return 0;
}

5.数组名

代码语言:javascript
复制
#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    printf("%d\n", *arr);
    //输出结果
    return 0;
 }

结论:

数组名是数组首元素的地址。(有两个例外)

1. sizeof( 数组名 ) ,计算整个数组的大小, sizeof 内部单独放一个数组名,数组名表示整个

2. & 数组名,取出的是数组的地址。 & 数组名,数组名表示整个数组

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 一维数组
    • 1.1 创建
      • 1.2 初始化
        • 1.3 使用
          • 1.4 存储
          • 2. 二维数组
            • 2.1 创建
              • 2.2 初始化
                • 2.3 使用
                  • 2.4 存储
                  • 3. 数组越界
                  • 4. 数组作为函数参数
                    • 4.1 冒泡排序函数
                      • 错误设计
                      • 正确设计
                  • 5.数组名
                  相关产品与服务
                  对象存储
                  对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档