C语言入门Part7--数组篇

C语言入门Part7–数组篇

**关键字:**数组常见问题及注意事项总结,字符串定义,一维数组在内存中的存储,sizeof()求数组长度的注意事项,sizeof()的用法注意,sizeof()strlen()的实例解析,一维数组的使用(冒泡排序及优化,选择排序,直接插入排序),二维数组的创建和初始化,二维数组打印:分别打印上三角 下三角 对称矩阵,二维数组的应用(三子棋,扫雷链接)

数组常见问题及注意事项总结

  1. 如果数组没有初始化,默认值为随机值。(局部数组)
  2. 数组的整体赋值只有一次机会,就是在初始化的同时 arr2=arr 也是错的,不能整体赋值
  3. 局部数组,是在什么时候确定大小的?
    编译的时候
  4. 什么时候分配内存?
    运行的时候
  5. 最大分配多大内存
    1M或2M取决于栈的大小(因为数组实在栈当中分配大小的,所以最大就是栈的大小)
  6. 整体初始化 局部初始化arr[10]={1,2};其余为0
  7. arr[ ]其中[]里面只能放常量
    注意
const int a=10;
int arr[a]={0};//错误   

错误原因:const修饰的是常变量,本质来说还是一个变量,只是这个变量被限制不能改变数值了而已

    #define SIZE 10;
    int main()
    {
    int arr[SIZE]={0};//正确
    ...
    }

推荐使用,后期若想改变数组大小就可以直接改变SIZE的值,便于代码的修改

字符串定义

char * p="abcd";
char arr[]="abcd";
char arr[5]="abcd";
char arr[5]={'a','b','c','d','\0'};

注意:打印时用%s
数组名:代表数组首元素的地址

一维数组在内存中的存储

int main()
{
	int a = 0;
	int b = 0;
	int arr[3] = { 0 };
	printf("a:%p\nb:%p\n",&a,&b);
	for (int i = 0; i < 3; i++)
	{
		printf("arr[%d]:%p\n",i, &arr[i]);
	}
	return 0;
}

在这里插入图片描述

  • 定义int a和int b,打印地址发现地址差16个字节,即中间空出两个int的字节,空出来的地址所占字节叫哨兵位,可以防止溢出
  • 运行结果可知数组会分配连续的内存==> 数组在内存中的存储是连续的
sizeof()求数组长度的注意事项

求数组长度公式len=sizeof(arr)/arr(arr[0]);
注意

  • 数组在哪里定义公式就在哪里使用
  • 一般数组名代表首元素的地址,但在两种情况下代表整个数组
    1.sizeof(arr)代表整个数组的字节大小
    2.&arr+1
  • 数组的传参,如果传数组名过来,那么就会退化为指针
    sizeof(指针)不论指针是什么类型结果都为4
    数组传参 void Show(int arr[])和void Show(int * arr)作用一样
       int arr[4] = { 1, 2, 3 };

       printf("%d ", sizeof(arr[4]));

执行结果是4,arr[4]越界但未报错,因为sizeof()是在编译期间处理,看表达式结果结果将来会是什么类型

拓展:sizeof()的用法注意
    int a =10;
    printf("%d %d", sizeof(++a),a);//结果 4 10

结果分析:因为sizeof()的结果是在编译期间确定的,里面的表达式并不会执行,所以最后a还是10

    printf("%d ", sizeof(1+3.2));//结果为8,默认3.2double类型
    printf("%d ", sizeof(1+3.2f));//结果为4,加f表flout

结果分析sizeof()默认求值结果是表达式中占字节大的结果

拓展:sizeof()strlen()的实例解析
char str1[100]="abcdef";
char str2[]="abcdef";
char * str3="abcdef";

char str4[100]="abcdef\0xyz";
char str5[]="abcdef\0xyz";
char * str6="abcdef\0xyz";

char str7100]="abcdef\n\0xyz";
char str8[]="abcdef\n\0xyz";
char * str9="abcdef\n\0xyz";

printf("%d,%d\n",sizeof(str1),strlen(str1));//100 6
printf("%d,%d\n",sizeof(str2),strlen(str2));//7(还算了默认自己加的\0) 6    
printf("%d,%d\n",sizeof(str3),strlen(str3));//4(sizeof(指针)都是4) 6

printf("%d,%d\n",sizeof(str4),strlen(str4));//100 6
printf("%d,%d\n",sizeof(str5),strlen(str5));//11(还算了默认自己加的\0) 6
printf("%d,%d\n",sizeof(str6),strlen(str6));//4  6

printf("%d,%d\n",sizeof(str7),strlen(str7));//100 7
printf("%d,%d\n",sizeof(str8),strlen(str8));//11(还算了默认自己加的\0) 7
printf("%d,%d\n",sizeof(str9),strlen(str9));//4  7 

一维数组的使用

实例1 冒泡排序法
#include<stdio.h>

void BubbleSort(int arr[],int len)

{

       int i = 0;

       for (i = 0; i < len - 1; i++)//控制趟数

       {

              for (int j = 0;j < len-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 i = 0;

       int arr[] = { 12,4,6,9,33,56,77 };

       int len = sizeof(arr) / sizeof(arr[0]);

       BubbleSort(arr,len);

       for (i = 0; i < len; i++)

       {

              printf("%d ", arr[i]);

       }

       return 0;

}
冒泡优化
#include<stdio.h>

void BubbleSort(int arr[],int len)

{

       int i = 0;

       int count = 0;//判断是否交换,未交换说明有序,有序则可直接跳出

       for (i = 0; i < len - 1; i++)//控制趟数

       {

              count = 0;

              for (int j = 0;j < len-1-i ; j++)

              {

                      if (arr[j] > arr[j + 1])

                      {

                             int tmp = arr[j];

                             arr[j] = arr[j + 1];

                             arr[j + 1] = tmp;

                             count = 1;

                      }

              }

              if (count == 0)

              {

                      break;

              }

       }

}
实例二 选择排序
void SelectSort(int arr[],int len)

{

       int i = 0;

       int j = 0;

       for (i = 0; i < len - 1; i++)

       {

              for (j = i + 1; j < len; j++)

              {

                      if (arr[i] > arr[j])

                      {

                             int tmp = arr[i];

                             arr[i] = arr[j];

                             arr[j] = tmp;

                      }

              }

       }

}
实例三 直接插入排序(越有序越快)
void InsertSort(int arr[],int len)

{

       for (int i = 1; i < len ; i++)

       {

              int tmp = arr[i];

              for (int j = i - 1; j >= 0; j--)

              {

                      if (tmp < arr[j])

                      {

                             arr[j + 1] = arr[j];

                      }

                      else

                      {

                             break;

                      }

              }

              arr[j + 1] = tmp;

       }

}


二维数组的创建和初始化

arr[][]  二维数组形式
arr[3][4]={0};  三行四列  整体初始化为零
int arr[2][2]={1,2,3,4};等价于 int arr[2][2]={{1,2},{3,4}};

二维数组初始化注意事项

  • 不可以同时不写行数和列数
  • 可以只写列数,编译器会根据列数确定行数 但是行数不能省略
  • 二维数组的内存也是连续的 二维数组是特殊的一维数组
  • 二维数组名还是代表数组首元素地址,但是此时的首元素是一个一维数组的地址
    == 》 所以需要定义一个指向数组的指针,即数组指针
    arr[3][3]={1,2,3,4,5,6,7,8,9} ;
    int (*p)[3]=arr;    
  • 二维数组传参要么写数组名,要么传数组指针。
    int * p[3];指针数组 存放指针的数组

  • []自带解引用 arr[i]就相当于*(arr+i)

  • 指针的加法
    int *(arr+i)相当于加i*sizeof(int)

  • 二维数组的初始化 循环嵌套

  • little tip:%-2d两位数左对齐打印


二维数组打印:分别打印上三角 下三角 对称矩阵
上三角

void UpAngle(int arr[][5], int row, int col)
{
    int m = 1;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            if (i<=j)
            {
                arr[i][j] = m;
                m++;
            }
            else
            {
                arr[i][j] = 0;
            }
        }
    }
}
int main()
{
    int arr[5][5] = { 0 };
    UpAngle(arr, 5, 5);
    return 0;
}
下三角

void UpAngle(int arr[][5], int row, int col)
{
    int m = 1;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            if (i>=j)
            {
                arr[i][j] = m;
                m++;
            }
            else
            {
                arr[i][j] = 0;
            }
        }
    }
}
对称
void SymMatrix(int arr[][5], int row, int col)

{

       int count = 1;

       for (int i = 0; i < row; i++)

       {

              for (int j = 0; j < col; j++)

              {

                      if (i<=j)

                      {

                             arr[i][j] = count++;

                      }

                      arr[j][i] = arr[i][j];

              }

       }

}

数组应用实例

由于篇幅原因将二维数组应用实例放置以下博客:
三子棋
https://blog.csdn.net/qq_43360037/article/details/97668012
扫雷
https://blog.csdn.net/qq_43360037/article/details/97697689
扫雷进阶版
https://blog.csdn.net/qq_43360037/article/details/100412331

猜你喜欢

转载自blog.csdn.net/qq_43360037/article/details/100668665