c语言学习第十一课——数组与三子棋游戏实现

简介: c语言学习第十一课——数组与三子棋游戏实现

1.一维数组的创建与初始化

1.1数组的创建

数组是一组相同类型数据的集合

tydef_t    arrname  [const_t]

c99标准前,数组的大小必须是常量表的式

c99标准中,引入变长数组的概念,及数组大小是可以用变量表示的。变长数组无法初始化。

int main()
{
  int arr[8];
  char ch[10];
  float arr2[15];
  return 0;
}

举例创建如上数组,创建格式为 类型+数组名+[数组大小]

1.2 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容进行赋值

int main()
{
  int arr[8] = { 1,2,3,4,5,6,7,8 };
  char ch[10] = { 'd','s','df','f','c','h','g' };
  float arr2[15] = { 1.23,5.65,7.32,5.62,9.35 };
  char arr3[] = "faoijfaj";//可以不指定大小,大小会根据初始化内容决定
  return 0;
}

初始化可以完全初始化,也可以不完全初始化,剩余的默认初始化为0,但绝不可以初始化超过数组大小。

这里须注意一下字符数组两种初始化的区别

char arr[]="fafafa".char arr2={'f','a','f','a','f','a'}  前者有结束标志“\0”,后者没有。

1.3一维数组的使用

利用下标引用操作符引用数组

int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9 };
  for (int i = 0; i < 10; i++)
  {
        printf("%d", arr[9]);
  }
  int size = sizeof(arr) / szieof(arr[0]);//计算数组元素个数
  return 0;
}

1.4一维数组的存储

因为数组的地址是连续存放的,我们在应用数组的地址时,当存放给一个指针时,该指针也可通过首地址找出后面元素的地址

所以在某种程度,指针可以表示数组,数组名代表一个指针。

我们先看看的地址

int main()
{
  int arr[10] = { 0 };
  int i = 0;
  int se = sizoef(arr) / sizeof(arr[0]);
  for (i = 0; i < se; i++)
  {
    printf("%p\n", &arr[i]);
  }
  return 0;
  //这里一个整型元素 4个字节,总大小为40字节。
  //打印出每个元素的地址 我们发现两两地址刚好差 4,即元素在数组中是连续存储的。
  //随着下标的递增,地址由低到高变化。
}

958a015ce1324db690300400eb9a16fd.png


再看看利用和指针实现数组元素的访问。

int main()
{
  int arr[10] = { 0 };
  int i = 0;
  int se = sizoef(arr) / sizeof(arr[0]);
  int* p = &arr[0];//int *p=arr;
  for (i = 0; i < se; i++)
  {
    printf("%p\n", p + i);
  }
  for (i = 0; i < se; i++)
  {
    printf("%d\n", *(p + i));//打印1到10
  }
  return 0;
}

2.二维数组

2.1二维数组的创建

类比于一维数组创建,这里直接创建二维数组。

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

在理解二维数组上,因为它1是二维,则我们理解为他是几行几列的数据存储,前一个代表行,后一个代表列,如同行列式里的方阵。

2.2二维数组的初始化

int main()
{
  int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//直接初始化
  char arr[5][6] = { {1,2},{3,4},{5,6} };//一行行的初始化,且不完全初始化
  //在这里初始化时,不同于一维数组可以省略数组大小,在二维数组中,行可以省略,
    //但列不能省略,
  //省略行,不省略列,计算机还是可以通过计算确定
    //数组的存储方式,但若省略了列,只有行,此时二维数组的存储情况较多,计算机无法判断。
  int arr[][4] = { {1,2},{3,4},{5,6} };
  return 0;
}

这里我们举例  int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//直接初始化

我们可以这样来理解它

786a9c0bff0448a4bbcfbd0fb18a57f5.png

2.3二维数组的使用

仍然通过下标来引用数组,且行列编号都是从0开始

int main()
{
  int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
  //1  2  3  4
  //5  6  7  8
  //9 10 11 12
  printf("%d", arr[1][2]);//打印7
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      printf("%2d", arr[i][j]);//右对齐2位打印整数 
    }
    printf("\n");
  }
  //打印数组的每一个元素
  //先行遍历,在列遍历,
  return 0;
}

2.4二维数组在内存中的存储

还是观察地址

int main()
{
  int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      printf("%p\n", &arr[i][j]);
    }
  }
  return 0;
}


d54084391eae4327b4e21073baefed2c.png

我们发现元素的地址还是连续的,故我们理解的是几行几列,但实际二维数组元素的地址是连续的。

与一维数组一样,我们知道了首地址,传给一个指针时,我们可以通过首地址间接访问二维数组的所有成员。

此时我们还可以这样理解二维数组:

我们将二维数组的每一行看做一个一维数组,则arr[0]就是第一行的数组名,arr[1]是第二行的数组名

......,相当于int arr[0]  [4],int arr[1]  [4],int arr[2]  [4],int arr[3]  [4]。

3.数组的越界

在数组下标访问的过程中,若访问超出数组大小范围,下标越界访问,编译器不一定会报错,但该代码已经是错误了。

4.数组作为函数参数

这里我们用冒泡排序来举例,数组做函数参数:

void bubble_sort(int arr[])//参数本质是一个指针  int * arr
{
  for (int i = 0; i < 10 - 1; i++)
  {
    for (int j = 0; j < 10 - i - j; j++)
    {
      if (arr[j] > arr[j+1])
      {
        int tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
      }
    }
  }
}
int main()
{
  int arr[] = { 4,6,8,2,8,6,9,5 };
  //排序
  bubble_sort(arr);
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d", arr[i]);
  }
  return 0;
}

我们发现在用数组传参时,本质上就是传的数组首元素的地址,所以在传参时,我们仍可以用对应类型的指针作为参数,来接收数组。

根据二维数组的特点,我们可以实现一个三子棋游戏。

具体如下:三子棋 - 代码片段 - Gitee.com

相关文章
|
2月前
|
C语言
扫雷游戏(用C语言实现)
扫雷游戏(用C语言实现)
104 0
|
12天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
38 4
|
19天前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
30 1
|
2月前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
40 6
|
2月前
|
存储 人工智能 BI
C语言:数组的分类
C语言中的数组分为一维数组、多维数组和字符串数组。一维数组是最基本的形式,用于存储一系列相同类型的元素;多维数组则可以看作是一维数组的数组,常用于矩阵运算等场景;字符串数组则是以字符为元素的一维数组,专门用于处理文本数据。
|
2月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
2月前
|
存储 C语言
C语言:一维数组的不初始化、部分初始化、完全初始化的不同点
C语言中一维数组的初始化有三种情况:不初始化时,数组元素的值是随机的;部分初始化时,未指定的元素会被自动赋值为0;完全初始化时,所有元素都被赋予了初始值。
|
2月前
|
C语言
C语言数组
C语言数组
21 0
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
36 3
|
1天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
22 6