【C】数组——知识点大全(简洁,详细)

 前言:大家好,这里是YY;此篇博客主要是数组的知识点;包含【一维数组】【二维数组】【二维数组的使用】【数组名的要点】【打印数组的两种方式】【数组的传参要点】【数组实际应用:三子棋索引】

PS:创作不易,每个知识点都有例题或者图帮助理解;如果对你有帮助,希望能够得到您的关注,赞,收藏,谢谢!  

目录

一.一维数组的创建

1.数组的基本形式

2.变长数组

3.数组的初始化 

二.数组的本质

三.一维数组的使用

1.访问数组成员

2.计算数组的大小

四.一维数组在内存中的存储

五.二维数组

1.二维数组的形式

2.二维数组的初始化规则

六.二维数组的使用

1.打印二维数组

七.二维数组在内存中的存储

八.数组越界的情况

九.数组名要点

1.数组名是首元素的地址(存在两个例外)

2.arr,&arr[0],&arr的区别(以及它们+1后的含义)

十.打印数组的两种写法

法一:利用下标引用操作符[](元素本身)

法二:解引用首元素地址(数组名/p)

小拓展:加法交换律的写法

十一.数组作为函数参数时

1.传参的两种形式

1.数组在传参的时候会发生数组名的降级(冒泡排序演示)

一:无法排序的情况

二:解决方式:别在函数内部求数组的个数

十二.数组的实际应用:三子棋 


一.一维数组的创建


1.数组的基本形式


2.变长数组

  • C99中引入了变长数组的概念
  • 变长数组支持数组的大小使用变量来指定,但是变长数组不能初始化
  • 变长数组不是数组的长度可以变化

 例:

int n=0;
scanf("%d",&n);
int arr[n];支持C99标准的编译器环境下能编译

3.数组的初始化 

  • 数组可以不给定范围,但是一定要初始化
  • 初始化分为完全初始化不完全初始化(除了初始化的元素,其余默认为0)
int arr1[2]={1,1};完全初始化
int arr2[10]={1}不完全初始化,第一个元素初始化为1,其余剩下都为0

二.数组的本质

  • 数组的本质是一类相同元素的集合

例:

 区别:


三.一维数组的使用


1.访问数组成员

  • 数组是使用下标(下标引用操作符)来访问的,下标从0开始
  • 数组的下标总是比个数小一位

例:


2.计算数组的大小


四.一维数组在内存中的存储

  • 一维数组在内存中的存储是连续存放
  • 随着数组下标的增长,地址也是从低到高变化的

        

  • 每一个内存单元大小就是一个字节(byte),即(int占4个内存单元)

 图示:


五.二维数组


1.二维数组的形式


2.二维数组的初始化规则

  • 放满一行,再来一行,其余初始化为0

      

  • { } 决定换行

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

  • 二维数组,行有几个可以不知道,列有几个必须知道
int arr[][4]={
    
    {1,2},{4,5}};

 


六.二维数组的使用

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

图示:


1.打印二维数组


七.二维数组在内存中的存储

  • 二维数组在内存中的储存也是连续存放
  • 随着数组下标的增长,地址也是从低到高变化的

     

PS:引申用法:当把每行当作一维数组时,数组名可视作行名

     

图示: 


八.数组越界的情况

  • 数组的下标有范围限制。数组的规定是从0开始,如果数组有n个元素,最后一个元素的下标就是n-1。如果数组的下标小于0或者大于n-1,数组越界访问。
  • C语言本身不做数组下标的越界检查,编译器不一定报错


九.数组名要点


1.数组名是首元素的地址(存在两个例外)

  1. sizeof(arr),数组名表示整个数组,计算的是整个数组的大小
  2. &arr,数组名表示整个数组,取出的是整个数组的地址

除此之外,遇到的数组名都是数组首元素的地址


2.arr,&arr[0],&arr的区别(以及它们+1后的含义)

  • arr与&arr[0]等效,表示首元素的地址
  • &arr表示数组的地址

PS:arr[n]表示第n+1个数组元素

代码演示: 

int arr[10]={0};

printf("%p\n",arr);首元素的地址
printf("%p\n",arr+1);首元素的地址+1

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

printf("%p\n",&arr);数组的地址
printf("%p\n",&arr+1);数组结尾下一个的地址

十.打印数组的两种写法

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

int*p=&arr[0]; p为首元素地址
int*p=arr;

法一:利用下标引用操作符[](元素本身)

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

法二:解引用首元素地址(数组名/p)

//int*p=&arr[0]; p为首元素地址
for(int i=0;i<10;i++)
{
  printf("%d",*(p+i));
  printf("%d",*(arr+i));
}

原理图示:


小拓展:加法交换律的写法

  •  arr[i]等效于i[arr]
int arr[10]={1,2,3,4,5,6,7,8,9,10};

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


十一.数组作为函数参数时


1.传参的两种形式

二者等效

void bubble_sort(int* arr);
void bubble_sort(int arr[10]);

1.数组在传参的时候会发生数组名的降级(冒泡排序演示)


一:无法排序的情况

void bubble_sort(int arr[10])
{
   //求数组的元素个数
   int sz=sizeof(arr)/sizeof(arr[0]);  问题点:此时的arr不再是数组,已经降级
   //冒泡排序的趟数
   int i=0;
   for(i=0;i<sz-1;i++)
   {
      int j=0;
      for(j=0;j<sz-1-i;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;
}

二:解决方式:别在函数内部求数组的个数

void bubble_sort(int arr[10])
{
   //冒泡排序的趟数
   int i=0;
   for(i=0;i<sz-1;i++)
   {
      int j=0;
      for(j=0;j<sz-1-i;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);
   //求数组的元素个数
   int sz=sizeof(arr)/sizeof(arr[0]);  改变点:此时arr为数组
   for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
   {
       printf("%d",arr[i]);
   }
   return 0;
}

十二.数组的实际应用:三子棋 

后续更新

猜你喜欢

转载自blog.csdn.net/YYDsis/article/details/130464796