c语言---数组

目录

一维数组

一、数组的创建

1.数组的创建方式:

2.数组的创建实例:

3.计算数组大小

二、数组的初始化

三、一维数组在内存中的存储

 二维数组

一、数组的创建

二、数组的初始化

三、二维数组在内存中的存储

数组作为函数参数

一、冒泡排序函数的错误设计

1.错误代码分析

2.数组名是什么?

二、冒泡排序函数的正确设计


一维数组

一、数组的创建

        数组是一组相同类型元素的集合。

1.数组的创建方式:

type_t   arr_name   [const_n];

type_t 是指数组的元素类型

const_n 是一个常量表达式,用来指定数组的大小 

2.数组的创建实例:

char arr3[10];

float arr4[1];

double arr5[20];

注:数组创建,在C99标准之前,[ ] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数 组的概念。

int main()
{
	const int n = 10;//常变量  也不行
	scanf("%d", &n);
	int arr[n];
    //C99中引入了变长数组的概念
    //允许数组的大小用变量来指定,如果编译器不支持C99中的变长数组,那就不能使用
	//VS2019是不支持变长数组的
	return 0;
}

3.计算数组大小

int main()
{
	int arr[200] = {1,2,3,4,5,6};
	printf("%d\n", sizeof(arr));     //800
	printf("%d\n", sizeof(arr[0]));  //4
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素个数的写法
	printf("%d\n", sz);              //200
	return 0;
}

二、数组的初始化

        数组在创建的时候如果想不指定数组的确定大小,就得初始化。数组的元素个数根据初始化的内容来确定。

int arr1[10] = {1,2,3};

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

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

char arr4[3] = {'a',98, 'c'};

char arr5[] = {'a','b','c'};

char arr6[] = "abcdef";

三、一维数组在内存中的存储

#include 
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int*p = &arr[0];
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	printf("\n");
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p <===> %p\n", i, &arr[i], p+i);
	}
	return 0;
}

%p  打印地址(16进制)

%d  打印整数(10进制)

        输出的结果如下:

c语言---数组_第1张图片

         仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。 由此可以得出结论:数组在内存中是连续存放的

c语言---数组_第2张图片

 

c语言---数组_第3张图片

 二维数组

一、数组的创建

int arr[3][4];

char arr[3][5];

double arr[2][4];

二、数组的初始化

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

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

int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略

三、二维数组在内存中的存储

#include 
int main()
{
	int arr2[][5] = { {1,2}, {4,5},{5,6} };
	int  i = 0;
	for (i = 0; i < sizeof(arr2)/sizeof(arr2[0]); i++)//0 1 2 
	{
		int j = 0;
		for (j = 0; j < sizeof(arr2[0])/sizeof(arr2[0][0]); j++)
		{
			printf("%d ", arr2[i][j]);
		}
		printf("\n");
	}
	int arr[3][5] = { {1,2}, {4,5},{5,6} };
	for (i = 0; i < 3; i++)//0 1 2 
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
		}
	}
	return 0;
}

         输出的结果是这样的:

c语言---数组_第4张图片

         通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。

c语言---数组_第5张图片

数组作为函数参数

        往往我们在写代码的时候,会将数组作为参数传个函数。比如:我要实现一个冒泡排序函数 将一个整形数组排序。

一、冒泡排序函数的错误设计

1.错误代码分析

#include 
void bubble_sort(int arr[])
{
     int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
     int i = 0;
     for(i=0; i 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

出问题,那我们找一下问题,调试之后可以看到 bubble_sort 函数内部的 sz ,是1

难道数组作为函数参数的时候,不是把整个数组的传递过去?

2.数组名是什么?

#include 
int main()
{
    int arr[10] = {1,2,3,4,5};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    printf("%d\n", *arr);
    return 0;
}

        结论:

数组名是数组首元素的地址。(但是有两个例外

例外:

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

二、冒泡排序函数的正确设计

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。 所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。 那么,函数内部的sizeof(arr) 结果是4。

void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
     int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
     int i = 0;
     for(i=0; i 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};
    int sz = sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr, sz);//是否可以正常排序?
    for(i=0; i

 

 

你可能感兴趣的:(c生万物,c语言)