欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言數(shù)組超詳細(xì)講解上

 更新時間:2022年04月13日 18:54:45   作者:初學(xué)C語言者  
數(shù)組是一組有序的數(shù)據(jù)的集合,數(shù)組中元素類型相同,由數(shù)組名和下標(biāo)唯一地確定,數(shù)組中數(shù)據(jù)不僅數(shù)據(jù)類型相同,而且在計算機(jī)內(nèi)存里連續(xù)存放,地址編號最低的存儲單元存放數(shù)組的起始元素,地址編號最高的存儲單元存放數(shù)組的最后一個元素

前言

本文主要介紹數(shù)組相關(guān)的內(nèi)容,主要內(nèi)容包括:

  • 一維數(shù)組的創(chuàng)建和初始化
  • 一維數(shù)組的使用
  • 一維數(shù)組在內(nèi)存中的存儲
  • 二維數(shù)組的創(chuàng)建和初始化
  • 二維數(shù)組的使用
  • 二維數(shù)組在內(nèi)存中的存儲
  • 數(shù)組越界
  • 數(shù)組作為函數(shù)參數(shù)

1、一維數(shù)組的創(chuàng)建和初始化

1.1 一維數(shù)組的創(chuàng)建

數(shù)組是一組相同類型元素的集合,數(shù)組的創(chuàng)建方式:

//type_t 是指數(shù)組的元素類型
//const_n 是一個常量表達(dá)式,用來指定數(shù)組的大小
type_t arr_name [const_n];

//代碼1
int arr1[10];
//代碼2
int count = 10;
int arr2[count];//數(shù)組不要放變量
//代碼3
char arr3[10];
float arr4[1];
double arr5[20];

注:數(shù)組創(chuàng)建,在C99標(biāo)準(zhǔn)之前, [ ] 中要給一個常量才可以,不能使用變量。在C99標(biāo)準(zhǔn)支持了變長數(shù)組的概念。

1.2 一維數(shù)組的初始化

數(shù)組的初始化是指,在創(chuàng)建數(shù)組的同時給數(shù)組的內(nèi)容一些合理初始值(初始化)

int arr[10] = {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'};//字符串也是通過數(shù)組定義的
char arr5[] = {'a','b','c'};//字符串也是通過數(shù)組定義的
char arr6[] = "abcdef";//字符串也是通過數(shù)組定義的

數(shù)組在創(chuàng)建的時候如果想不指定數(shù)組的確定的大小就得初始化。數(shù)組的元素個數(shù)根據(jù)初始化的內(nèi)容來確定。

仔細(xì)對比下面5個數(shù)組:

	char arr1[] = "abc";
	char arr2[3] = { 'a','b','c' };
	char arr3[] = { 'a','b','c' };
	char arr4[4] = { 'a','b','c' };
	char arr5[] = { 'a','b','c','\0' };

	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	printf("%s\n", arr4);
	printf("%s\n", arr5);
	printf("\n");
	printf("%d\n", sizeof(arr1));
	printf("%d\n", sizeof(arr2));
	printf("%d\n", sizeof(arr3));
	printf("%d\n", sizeof(arr4));
	printf("%d\n", sizeof(arr5));

對比下面兩圖可知,字符串以字符 ‘\0’ 為結(jié)尾:

  • arr1 用雙引號存儲字符串時,末尾有隱藏的 ‘\0’ ,字符串長度為4
  • arr4 規(guī)定了字符串的長度,末尾也有隱藏的 ‘\0’ ,字符串長度為4
  • arr5 規(guī)直接末尾添加了 ‘\0’ ,字符串長度為4
  • arr3 和 arr4都是只有三個字符,字符串長度為3,但是末尾沒有 ‘\0’ ,字符串沒有結(jié)束,打印出來后面是亂碼的

下面兩圖的結(jié)果能清楚的表示,上面5中定義的區(qū)別,因此,推薦使用數(shù)組arr1的方式定義字符串。

在這里插入圖片描述

在這里插入圖片描述

1.3 一維數(shù)組的使用

對于數(shù)組的使用我們之前介紹了一個操作符: [ ] ,下標(biāo)引用操作符。它其實就數(shù)組訪問的操作符。

int main()
{
	int arr[10] = {0};//數(shù)組的不完全初始化
	//計算數(shù)組的元素個數(shù)= 整個數(shù)組的大小/數(shù)組首元素的大小
	int sz = sizeof(arr)/sizeof(arr[0]);
	//對數(shù)組內(nèi)容賦值,數(shù)組是使用下標(biāo)來訪問的,下標(biāo)從0開始。所以:
	int i = 0;//做下標(biāo)
	//for(i=0; i<sz; i++)//這樣也行
	for(i=0; i<10; i++)
	{
		arr[i] = i;//給數(shù)組元素初始化
	}
	//輸出數(shù)組的內(nèi)容
	for(i=0; i<10; ++i)
	{
		printf("%d ", arr[i]);//打印數(shù)組
	}
	return 0;
}

數(shù)組是使用下標(biāo)來訪問的,下標(biāo)是從0開始。 數(shù)組的大小可以通過計算得到的。

1.4 一維數(shù)組在內(nèi)存中的存儲

接下來探討數(shù)組在內(nèi)存中的存儲

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//打印數(shù)組中的每個元素的地址
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	int* p = &arr[0];//元素首地址
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(p++));//地址加1
	}	
	return 0;
}

兩種打印數(shù)組的方式都可以,結(jié)果相同:

在這里插入圖片描述

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//打印數(shù)組中的每個元素的地址
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = &arr[0];//元素首地址
	for (int  i = 0; i < sz; i++)
	{//打印地址
		printf("&arr[%d]=%p <==> %p\n", i, &arr[i], p++);
	}
	return 0;
}

輸出結(jié)果見下圖,隨著數(shù)組下標(biāo)的增長,元素的地址,也在有規(guī)律的遞增。整形數(shù)組每個元素占4個字節(jié),共10個元素,總共40個字節(jié)。所以相鄰元素的地址依次遞增4個字節(jié)。

由此可以得出結(jié)論:數(shù)組在內(nèi)存中是連續(xù)存放的。

在這里插入圖片描述

在這里插入圖片描述

2、二維數(shù)組的創(chuàng)建和初始化

2.1 二維數(shù)組的創(chuàng)建

//數(shù)組創(chuàng)建
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 二維數(shù)組的初始化

//數(shù)組初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二維數(shù)組如果有初始化,行可以省略,列不能省略
int arr1[][5] = { 1,2,3,4,5,6 };//不完全初始化
int arr2[][5] = { {1,2},{3,4},{5,6} };
char ch[5][7];
int arr[4][5] = { 0 };

2.3 二維數(shù)組的使用

二維數(shù)組的使用也是通過下標(biāo)的方式

int main()
{
	int arr2[][5] = { {1,2},{3,4},{5,6} };

	for (int i = 0; i < sizeof(arr2) / sizeof(arr2[0]); i++)//打印二維數(shù)組
	{
		//int j = 0;
		for (int j = 0; j < sizeof(arr2[0]) / sizeof(arr2[0][0]); j++)
		{
			printf("%d ", arr2[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在這里插入圖片描述

2.4 二維數(shù)組在內(nèi)存中的存儲

像一維數(shù)組一樣,打印二維數(shù)組的每個元素

int main()
{
	int arr[3][5] = { {1,2},{3,4},{5,6} };
	for (int i = 0; i < 3; i++)
	{
		int j = 0;
		for ( j = 0; j < 5; j++)
		{
			printf("&arr[%d]{%d]=%p\n", i, j, &arr[i][j]);//地址是連續(xù)的
		}
	}
	return 0;
}

二維數(shù)組的地址在內(nèi)存中也是連續(xù)的,相鄰元素依次相差4個字節(jié),&arr[0][3]與&arr[1][0]是相連的。

在這里插入圖片描述

在這里插入圖片描述

3、數(shù)組越界

  • 數(shù)組的下標(biāo)是有范圍限制的
  • 數(shù)組的下規(guī)定是從0開始的,如果數(shù)組有n個元素,最后一個元素的下標(biāo)就是n-1。所以數(shù)組的下標(biāo)如果小于0,或者大于n-1,就是數(shù)組越界訪問了,超出了數(shù)組合法空間的訪問
  • C語言本身是不做數(shù)組下標(biāo)的越界檢查,編譯器也不一定報錯,但是編譯器不報錯,并不意味著程序就是正確的,所以程序員寫代碼時,最好自己做越界的檢查
  • 二維數(shù)組的行和列也可能存在越界。
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0; i<=10; i++)
{
printf("%d\n", arr[i]);//當(dāng)i等于10的時候,越界訪問了
}
return 0;
}

4、數(shù)組作為函數(shù)參數(shù)

往往我們在寫代碼的時候,會將數(shù)組作為參數(shù)傳個函數(shù),比如:要實現(xiàn)一個冒泡排序函數(shù),將一個整形數(shù)組排序

4.1 冒泡排序函數(shù)的錯誤設(shè)計

//方法1:
void bubble_sort(int arr[])//接受數(shù)組
{//計算數(shù)組的長度
	int sz = sizeof(arr)/sizeof(arr[0]);
	int i = 0;
	for(i=0; i<sz-1; i++)
	{
		int j = 0;
		for(j=0; j<sz-i-1; j++)
		{
			if(arr[j] > 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);//將數(shù)組作為參數(shù)傳遞
	for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

結(jié)果見下圖,沒有達(dá)到預(yù)期的排序效果。

在這里插入圖片描述

按下F10進(jìn)入調(diào)試界面,按F11進(jìn)行單步調(diào)試,會發(fā)現(xiàn)主函數(shù)中的數(shù)組是10個元素,這是自己定義的,沒有問題。

在這里插入圖片描述

但是將數(shù)組當(dāng)作參數(shù)傳遞給函數(shù)bubble_sort會發(fā)現(xiàn),函數(shù)接受的數(shù)組只包含首元素3。

在這里插入圖片描述

因此計算數(shù)組長度sizeof(arr)時,結(jié)果長度是4,不再是原來主函數(shù)里的40了。

在這里插入圖片描述

調(diào)試之后可以看到 bubble_sort 函數(shù)內(nèi)部的 sz ,是1。

所以數(shù)組作為函數(shù)參數(shù)的時候,不是把整個數(shù)組的傳遞過去。

這種情況之前在C語言函數(shù)超詳細(xì)講解上篇中 4.3.3 二分查找中就具體分析過。

4.2 數(shù)組名是什么?

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);//首元素的地址
	printf("%p\n", arr+1);//+1指向第二個元素

	printf("%p\n", &arr[0]);//首元素的地址
	printf("%p\n", &arr[0]+1);+1//指向第二個元素

	printf("%p\n", &arr);//整個數(shù)組的地址
	printf("%p\n", &arr+1);

	return 0;
}

運行結(jié)果見下圖:

  • 數(shù)組名就是首元素的地址,用指針接收
  • 對數(shù)組名求地址,是整個數(shù)組的地址
  • &arr的地址和 &arr+1 的地址相差28,這是16進(jìn)制,轉(zhuǎn)化為2進(jìn)制就是 40了,這正是數(shù)組的長度,包含10個元素

在這里插入圖片描述

在這里插入圖片描述

4.3 對數(shù)組名的用法進(jìn)行總結(jié)

  • sizeof(數(shù)組名),計算整個數(shù)組的大小,sizeof內(nèi)部單獨放一個數(shù)組名,數(shù)組名表示整個數(shù)組。
  • &數(shù)組名,取出的是數(shù)組的地址。&數(shù)組名,數(shù)組名表示整個數(shù)組。
  • 除此1,2兩種情況之外,所有的數(shù)組名都表示數(shù)組首元素的地址。

4.4 冒泡排序函數(shù)的正確設(shè)計

上述代碼當(dāng)數(shù)組傳參的時候,實際上只是把數(shù)組的首元素的地址傳遞過去了。

所以即使在函數(shù)參數(shù)部分寫成數(shù)組的形式: int arr[] 表示的依然是一個指針: int *arr 。因為地址可以用指針就收。

那么,函數(shù)內(nèi)部的 sizeof(arr) 結(jié)果是4。數(shù)組長度應(yīng)該放在主函數(shù)中進(jìn)行計算。

下面對4.2 進(jìn)行改進(jìn),有時候數(shù)組元素本身就是按一定順序排好的,只需第一輪判斷即可:

void bubble_sort(int* arr, int sz)
{
	//排序坐外面的大循環(huán)次數(shù)
	int i = 0;
	for ( i = 0; i < sz-1; i++)
	{
		int flag = 1;//狀態(tài)機(jī)標(biāo)志位,代表數(shù)組本身元素就是從小到大排序的
		int j = 0;
		for ( j = 0; j < sz-1-i; j++)
		{
			if (arr[j]>arr[j+1])
			{
				flag = 0;//只要有一個地方需要排序,就置零
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (1==flag)
		{//第一輪排序結(jié)果都是1,說明沒有地方需要排序
			break;//直接跳出后面的循環(huán),不需要再排序了
		}
	}
}
int main()
{
	//int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr[] = { 3,1,2,4,5,6,8,9,7,10 };
	//寫一個冒泡排序的函數(shù),
	//arr表示首元素的地址, &arr[0],也是首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for ( i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在這里插入圖片描述

總結(jié)

本文是對數(shù)組相關(guān)知識點的學(xué)習(xí),下一篇將通過完成三子棋游戲鞏固前面所學(xué)的知識點。

到此這篇關(guān)于C語言數(shù)組超詳細(xì)講解上的文章就介紹到這了,更多相關(guān)C語言 數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Opencv實現(xiàn)雙目攝像頭拍照程序

    基于Opencv實現(xiàn)雙目攝像頭拍照程序

    這篇文章主要為大家詳細(xì)介紹了基于Opencv實現(xiàn)雙目攝像頭拍照程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • C/C++中虛基類詳解及其作用介紹

    C/C++中虛基類詳解及其作用介紹

    這篇文章主要介紹了C/C++中虛基類的詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Qt下監(jiān)測內(nèi)存泄漏的方法

    Qt下監(jiān)測內(nèi)存泄漏的方法

    在寫Qt應(yīng)用程序時,由于是采用C++語言,經(jīng)常會碰到一個令人棘手的問題,那就是內(nèi)存泄漏,本文主要介紹了Qt下監(jiān)測內(nèi)存泄漏的方法,感興趣的可以了解一下
    2021-12-12
  • 深度理解C語言中的關(guān)鍵字static

    深度理解C語言中的關(guān)鍵字static

    在C語言中static主要定義全局靜態(tài)變量、定義局部靜態(tài)變量、定義靜態(tài)函數(shù),下面這篇文章主要給大家介紹了關(guān)于C語言中關(guān)鍵字static的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • C++實現(xiàn)投骰子的隨機(jī)游戲

    C++實現(xiàn)投骰子的隨機(jī)游戲

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)投骰子的隨機(jī)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 關(guān)于數(shù)據(jù)結(jié)構(gòu)單向鏈表的各種操作

    關(guān)于數(shù)據(jù)結(jié)構(gòu)單向鏈表的各種操作

    這篇文章主要介紹了關(guān)于數(shù)據(jù)結(jié)構(gòu)單向鏈表的各種操作,關(guān)于數(shù)據(jù)結(jié)構(gòu)鏈表的操作一般涉及的就是增刪改查,下面將關(guān)于無空頭鏈表展開介紹,需要的朋友可以參考下
    2023-04-04
  • C語言實現(xiàn)簡單學(xué)生管理系統(tǒng)

    C語言實現(xiàn)簡單學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單學(xué)生管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 基于C語言模擬實現(xiàn)人生重開模擬器游戲

    基于C語言模擬實現(xiàn)人生重開模擬器游戲

    人生重開模擬器是前段時間非常火的一個小游戲,所以本文我們將一起學(xué)習(xí)使用c語言寫一個簡易版的人生重開模擬器,感興趣的小伙伴可以了解下
    2024-02-02
  • C++中virtual繼承的深入理解

    C++中virtual繼承的深入理解

    本篇文章是對C++中的virtual繼承進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用

    詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用

    這篇文章主要介紹了詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-08-08

最新評論