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语言之斗地主游戏
该代码实现了一个简单的斗地主游戏,包括头文件引入、宏定义、颜色枚举、卡牌类、卡牌类型类、卡牌组合类、玩家类、游戏主类以及辅助函数等,涵盖了从牌的生成、分配、玩家操作到游戏流程控制的完整逻辑。
87 8
|
1月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
98 6
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
72 5
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
53 2
|
2月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
2月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
61 4
|
算法 编译器 程序员
C语言学习笔记—P11(数组<2>+图解+题例+三子棋游戏<初级>)
C语言学习笔记(数组<2>+图解+题例+三子棋游戏<初级>)
140 0
C语言学习笔记—P11(数组<2>+图解+题例+三子棋游戏<初级>)
|
存储 C语言
C语言学习笔记—P10(数组<1>+图解+题例)
C语言学习笔记(数组<1>+图解+题例)
149 0