04_数组(一)

一维数组

一 概念

什么是数组?

一组具有相同数据类型的元素的集合。

元素:组成数组的基本单位。

注意:

1 数组的内存是连续的(长度有限)
2 数组长度:元素的个数
3 同一个数组存同样的数据类型

 

二 定义

// 数据类型 变量名 ;
int num;
// 元素类型 数组名[数组长度] ;
int card[16];

注意:

1 数组长度必须是常量
2 数组长度在有些时候可以不写,但是[]一定要写
3 数组长度可以是宏定义或const(#define NUM 16)(const int num = 10;)

 

三 值

1 初始化

int card[10] = {};
1 {}里面 不写

全部元素 值默认为0

2 {}里面 写部分

没有初始值的元素 值默认为0

3 {}里面 写满
4 {}里面 写多了
小结:
1 {}里面 可以不写或写部分或写满 但是值的个数 不能超过数组长度
2 在初始化时 可以不写数组长度
(但是 [] 一定要写)
(一定要有{}里的初始值)
(初始值有几个数组长度就默认为几)
3 数组长度可以用 sizeof() 来求 求出来的是字节数(求元素个数:sizeof(数组名)/sizeof(元素类型))

 

2 赋值

1 涉及到访问数组元素,因为要访问到具体的元素才好赋值

2 访问到元素后,和普通赋值一样

 

四 访问

1 下标访问

· 数组下标从0开始 到数组长度-1
    int card2[10];  // 定义了长度为10、元素类型为int的 一维数组card2
card2[0] = 1; // 给数组第0个元素 赋值为1

// 通过循环 遍历数组 将元素赋值
for (int i = 0; i < 10; i++)
{
card2[i] = i;
}
// 通过循环 遍历数组 打印数组元素的值
for (int i = 0; i < 10; i++)
{
cout << card2[i] << " ";
}

注意:

一定不要数组越界
越界:超过了界限

2 通过指针偏移

 

 

· 数组应用举例

/*
使用十六进制数,
右起第一位表示点数 3 -- A   : 3 -- E   2 : 1
右起第二位表示花色 A B C D G : ♥ ♠ ♣ ◆ 王
*/

// 玩家二的牌
int card2[16] = {
       0XA3, 0XA4, 0XA5, 0XA6, 0XA7,
       0XA9, 0XB9, 0XC9,
       0XDA, 0XAB, 0XCC, 0XBD, 0XBE,
       0XB1,
       0XB3, 0xC6};

//出牌
card2[7] = 0;

// 展示牌
for (int i = 0; i < sizeof(card2)/sizeof(int); i++)
{
       // 花色
switch (card2[i]/16%16)
{
case 10:
cout << "红桃";
break;
case 11:
cout << "黑桃";
break;
case 12:
cout << "梅花";
break;
case 13:
cout << "方块";
break;
default:
break;
}
       // 点数
switch (card2[i]%16)
{
case 11:
cout << "J" << endl;
break;
case 12:
cout << "Q" << endl;
break;
case 13:
cout << "K" << endl;
break;
case 14:
cout << "A" << endl;
break;
case 1:
cout << "2" << endl;
break;
case 0:
cout << "" << endl;
break;
default:
cout << card2[i] % 16 << endl;
break;
}

}

 

五 字符数组

· 字符数组也是数组(也就是说,具有数组的特征)

1 定义、赋值、初始化

// 情况1
char arr1[10];
// 正确赋值方法:
arr1[0] = 'a';
for (int i = 0; i < 10; i++)
{
arr1[i] = 65 + i;
}
// 错误赋值方法:
// arr1 = "sygjh";
for (int i = 0; i < 10; i++)
{
printf("%c ", arr1[i]);
}
// 情况2
char arr2[10] = { 'a', 'b', 'c', 'd', 'e' };
for (int i = 0; i < 10; i++)
{
printf("%c ", arr2[i]);
}
//1 在这种情况下,{}里面,可以不写、写以一部分、写满,但是不能多写
//2 没给值的元素,有默认值为'\0'
// 情况3
char arr3[10] = "abcd";
for (int i = 0; i < 10; i++)
{
printf("%c ", arr3[i]);
}
// 可以直接用字符串给字符数组初始化,没有初始值的元素,有默认值为'\0'
// 情况4
char arr4[] = "abcdefg";
for (int i = 0; i < sizeof(arr4)/sizeof(char); i++)
{
printf("%c ", arr4[i]);
}
sizeof(arr4); //8
// 发现:最后会打印一个0(%d)
// 探究:求sizeof(arr4) 结果为:8 字符串可以看到7个字符
// 分析:字符串结尾处,有一个看不见的字符 (是数组的问题还是字符串的问题?)
// 探究:求sizeof("abcdefg"); 结果为:8
// 结论1:问题来自于字符串 ==> 字符串结尾处有一个看不见的字符被存到了数组中
// 结论2:数组最后一个元素的值是'\0' ASCII码值为0
// 结论3:字符串结尾处有一个看不见的字符'\0'
// 这个字符是字符串结束的标志,字符串中的'\0'是系统自动补齐的
// 注意:在用字符串给字符数组初始化时注意数组长度

小结:

1 定义、赋值和普通数组一致

2 初始化时可以直接用字符串,但是要注意:1.结尾的'\0' 2.转义字符

    char arr[] = "a\tbc\123d\xa4g\018";
cout << sizeof(arr) << endl;
// a \t b c \123 d \xa4 g \01 8
// 字符串中 转义字符后面 八、十六进制最大:377、FF( '\377' '\XFF' '\xff' )

补充:

打印字符数组时可以用循环遍历打印 也可以直接打印字符串
    char ch1[] = "abcdeFGHiJkLMn";
printf("%s\n", ch1);

 

六 排序

一、冒泡排序

  原理解析:(以从小到大排序为例)在一排数字中,将第一个与第二个比较大小,如果后面的数比前面的小,则交换他们的位置。

然后比较第二、第三个……直到比较第n-1个和第n个,此时,每一次比较都将较大的一个数往后移动,所以第n个数是所有数中最大的一个。

之后再重复以上过程,直到将所有数据按从小到大顺序排列好。

  编程实现:通过两个嵌套的循环实现。外层循环执行一次,内层循环执行一遍。

其中,内层循环控制比较时的下标,外层循环控制比较的总次数。

  注意:

    1、每多排好一个数,可以将内层循环次数减少一次,从而程序运行提高效率。

    2、总共只需为n-1个数排序,剩下的一个为最小值,不需再排序。

  对于从大到小排序是同样的原理。

代码:

#include <stdio.h>
int main()
{
  /* 定义一个未序一维数组 */
  int a[10] = { 1,2,3,6,5,4,7,0,8,-3};
  /* 外层循环 控制比较“趟数”,每一趟排好一个数 */
  for( int i = 9; i > 0; i-- )
  {
    /* 内存循环 控制冒泡“次数”,每次向后冒泡 */
    /* 次数受外层循环控制,每趟少冒泡一次*/
    for (int j =0; j<i; j++)
    {
      /* 当前元素为a[j] 如果当前元素大于下一个元素a[j+1],交换值 */
      if (a[j] > a[j+1] )
      {
        /* 使用位运算 不通过第三方变量交换两个变量的值 */
        a[j] = a[j]^a[j+1];
        a[j+1] = a[j]^a[j+1];
        a[j] = a[j]^a[j+1];
      }
    }
  }
  /* 遍历输出已序数组 */
  for (int i = 0; i < 10; i++)
    printf("%d ",a[i]);
  return 0;
}

二、选择排序

  选择排序可以看做是冒泡排序的优化。在选择排序中,内层循环只负责寻找最大值的下标并保存,不需要频繁交换值。

  原理解析:1、在n个数中,先找到最大的数并记录其下标,然后将这个数与第n个数交换值,如果刚好第n个数是最大数则不用交换。

       2、重复第一步,直到所有数排好顺序

  编程实现:两层循环嵌套,内循环寻找最大值的下标。

  注意:选择最大值可以假定第0个元素是最大的,碰到比他大的值就更新 int maxIndex;

     每次循环之前,maxIndex必须归0。

代码:

#include <stdio.h>
void main()
{
  int a[10] = { 5, 1, 6, 9, -8, 3, 4, 6, 10, 7 };
  int maxindex = 0 ,  temp;
  for (int j = 9; j > 0; j--)
  {
    maxindex = 0;
    for (int i = 1; i <= j; i++)
    {
      if (a[maxindex] < a[i])
      {
        maxindex = i;
      }
    }
    if (maxindex != j)
    {
      temp = a[maxindex];
      a[maxindex] = a[j];
      a[j] = temp;
    }
  }
  for (int i = 0; i<10; i++)
    printf("%d ", a[i]);
}

三、插入排序

  原理解析:将元素插入到已序数组中的相应位置,未排序数组将第一个元素视为已序数组。

  代码实现:将第一个元素视为已序数列,按排序规则选择位置插入。两层循环嵌套,内层循环控制比较的次数。

代码:

#include <iostream>
using namespace std;

int main()
{
  int temp = 0;
  int a[10] = { 0 };
  cout << "请输入十个数:" << endl;
  for (int i = 0; i < 10; i++)
    cin >> a[i];

  // for循环,进行9次循环;
  for (int i = 1; i < 10; i++)
  // for循环,在每次大的循环中,a[i]从a[1]依次与它前面的数比较;
  for (int j = i - 1; j >= 0; j--)
    //如果a[j + 1]>a[j],则把这两个数组元素互换,目的把最大的数放到前边;
    if (a[j + 1] > a[j])
    {
      temp = a[j + 1];
      a[j + 1] = a[j];
      a[j] = temp;
    }else
      break;

  //输出排好顺序的十个数;
  for (int i = 0; i < 10; i++)
    cout << a[i] << " ";

return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-07-30 19:26  Zhen_X  阅读(191)  评论(0编辑  收藏  举报