免費做兼職的網(wǎng)站有嗎優(yōu)化網(wǎng)站排名解析推廣
七:C語言-數(shù)組
- 數(shù)組是一組相同類型元素的集合
- 數(shù)組中存放的是1個或者多個數(shù)據(jù),但是數(shù)組元素個數(shù)不能為0
- 數(shù)組中存放的多個數(shù)據(jù),類型是相同的
- 數(shù)組分為一維數(shù)組和多維數(shù)組,多維數(shù)組一般比較多見的是二維數(shù)組
- 存放在數(shù)組中的值被稱為數(shù)組的元素,數(shù)組在創(chuàng)建的時候可以指定數(shù)組的大小和數(shù)組的元素類型
一:一維數(shù)組
1.一維數(shù)組的創(chuàng)建:
語法格式:
type arr_name[常量值];
type
:指定的是數(shù)組中存放數(shù)據(jù)的類型,可以是char
;short
;int
;float
等,也可以是自定義類型arr_name
:指的是數(shù)組的名字[]
:包裹的是常量值,用來指定數(shù)組的大小的;在C99
標準之前定義數(shù)組的大小只能是由常量指定,不能使用變量。
示例:創(chuàng)建一個數(shù)組
int math[10]; //創(chuàng)建一個長度為10,int類型的數(shù)組元素
char people[3]; //創(chuàng)建一個長度為3,char類型的數(shù)組元素
double English[14]; //創(chuàng)建一個長度為14,double類型的數(shù)組元素
2.一維數(shù)組的初始化
數(shù)組在創(chuàng)建的時候,我們有時會根據(jù)一些實際的需求給定一些初始值,這就叫初始化;數(shù)組的初始化一般是使用大括號將數(shù)據(jù)包裹在其中。
示例:數(shù)組初始化
//完全初始化
int arr1[5] = {1,2,3,4,5}; //這里指的是數(shù)組的元素類型為int//不完全初始化
int arr2[6] = {1}; //第一個元素的初始化為1,剩余的元素默認初始化為0//錯誤的初始化 -- 初始化項過多
int arr3[4] = {1,2,3,4,5};//如果數(shù)組初始化了,是可以省略掉數(shù)組的大小的;數(shù)組的大小,是編譯器根據(jù)初始化的內(nèi)容確定的
int arr4[] = {1,2,3}; //此時數(shù)組的大小為3
注意: 數(shù)組也是有類型的,數(shù)組算是一種自定義類型,去掉數(shù)組名留下的就是當前數(shù)組的類型
3.一維數(shù)組的使用
C語言規(guī)定數(shù)組是有下標的,下標從0開始,假設數(shù)組有n個元素,那么最后一個元素的下標就是n-1,下標就相當于是對數(shù)組元素的編號
示例:
//定義一個int類型的數(shù)組
int arr5[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
圖解:
在C語言中為數(shù)組的訪問提供了一個操作符[]
,這個操作符叫做下標引用操作符
示例:
#include <stdio.h>
int main()
{//定義一個int類型的數(shù)組int arr5[12] = {1,2,3,4,5,6,7,8,9,10,11,12};//訪問下標為7的元素(也就是8)printf("%d\n",arr5[7]);return 0;
}
示例:通過下標打印所有元素(數(shù)組的輸出)
#include <stdio.h>
int main()
{//定義一個int類型的數(shù)組int arr5[12] = {1,2,3,4,5,6,7,8,9,10,11,12};//通過下標打印所有元素int i = 0;for(i=0;i<12;i++){printf("%d ",arr5[i]);}return 0;
}
示例:給數(shù)組輸入自己想要的數(shù)據(jù)(數(shù)組的輸入)
#include <stdio.h>
int main()
{//定義一個int類型的數(shù)組int arr5[12] = {1,2,3,4,5,6,7,8,9,10,11,12};//輸入int i = 0;for(i=0;i<12;i++){scanf("%d",&arr5[i]);}return 0;
}
4.一維數(shù)組在內(nèi)存中的存儲
示例:依次打印數(shù)組元素的內(nèi)存地址
#include <stdio.h>
int main()
{int arr[5] = {1,2,3,4,5};int i = 0;for(i=0;i<5;i++){printf("&arr[%d] = %p\n",i,&arr[i]); //打印地址的占位符是%p}return 0;
}
從輸出結果可以看出,數(shù)組隨著下標的增長,地址是由低到高變化的,并且每兩個相鄰的元素之間相差為4(因為1個int
整型是4個字節(jié));所以得出一個結論:數(shù)組在內(nèi)存中是連續(xù)存放的。
5.sizeof()
計算元素個數(shù)
sizeof()
是C語言中的一個關鍵字,作用是用來計算類型或者變量所占內(nèi)存空間的大小的,同時也可以用來計算數(shù)組所占內(nèi)存空間的大小和數(shù)組中的元素個數(shù)。
示例:使用
sizeof()
求元素個數(shù)
#include <stdio.h>
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10}; //這個數(shù)組是10個元素,而每個元素占4個字節(jié)printf("%d\n",sizeof(arr)); //sizeof(數(shù)組名)計算的是數(shù)組所占內(nèi)存空間的大小,并不是元素的個數(shù)/長度。單位是字節(jié),結果是40printf("%d\n",sizeof(arr[0])); //求1個元素所占內(nèi)存空間的大小printf("%d\n",sizeof(arr) / sizeof(arr[0])); //用整個數(shù)組所占內(nèi)存空間的大小除以1個元素所占內(nèi)存空間的大小,所得出的結果就是這個數(shù)組的元素個數(shù)return 0;
}
示例:使用
sizeof()
打印每個元素
#include <stdio.h>
int main()
{int arr[10] = {1,2,3};int r = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i=0;i<r;i++){printf("%d ",arr[i]);}return 0;
}
擴展:在計算一個類型所占內(nèi)存空間的大小的時候,可以用它的類型,也可以用變量名
#include <stdio.h>
int main()
{int a = 10;printf("%d\n",sizeof(a));printf("%d\n",sizeof a); //在求變量名所占內(nèi)存空間的大小的時候,可以省略掉()printf("%d\n",sizeof(int));return 0;
}
注意:
sizeof()
的計算結果是size_t
類型的,size_t
是無符號的整型類型
size_t
類型的打印格式使用%zd
占位符來打印的,但如果%zd
報錯的話,就用%d
;主要是看編譯器
二:二維數(shù)組
數(shù)組的元素都是內(nèi)置類型的,如果把一維數(shù)組做為數(shù)組的元素,那么這個數(shù)組就被稱為二維數(shù)組;依此類推,如果把二維數(shù)組做為數(shù)組的元素,那么這個數(shù)組就被稱為三維數(shù)組,三維數(shù)組以上的數(shù)組統(tǒng)稱為多維數(shù)組。
1.二維數(shù)組的創(chuàng)建
語法格式:
type arr_name[常量值1][常量值2];
- type
:指定的是數(shù)組中存放數(shù)據(jù)的類型,可以是
char;
short;
int;
float`等,也可以是自定義類型 arr_name
:指的是數(shù)組的名字[]
:包裹的是常量值,用來指定數(shù)組的大小的;在C99
標準之前定義數(shù)組的大小只能是由常量指定,不能使用變量。- 常量值1:用來指定數(shù)組有幾行
- 常量值2:用來指定數(shù)組有幾列
示例:
int arr[3][5];//int表示數(shù)組的每個元素都是整數(shù)類型
//arr是數(shù)組名
//3表示數(shù)組有3行
//5表示數(shù)組每一行有5個元素
2.二維數(shù)組的初始化
在創(chuàng)建變量或者數(shù)組的時候,給定一些初始值,被稱為初始化,二維數(shù)組也是使用大括號進行初始化的
示例:二維數(shù)組的初始化是一行一行放的,當元素把一行放滿后,才會進入下一行
#include <stdio.h>
int main()
{//不完全初始化int arr1[3][5] = {1,2};int arr2[2][6] = {0};int arr3[4][8] = {1,2,3,4,5,6};//完全初始化int ar1[3][5] = {1,1,1,1,1,2,2,2,2,2,3,3,3,3,3};//按照行來進行初始化int a1[3][5] = {{1,2},{3,4}{5,6,7}};//二維數(shù)組在初始化時可以省略行但不能省略列int arr4[][5] = {1,2,3}; //這里有1行int arr5[][4] = {1,2,3,4,5,6}; //這里有2行int arr6[][3] = {{1,2},{3,4},{5,6}}; //這里有3行return 0;
}
3.二維數(shù)組的使用
對二維數(shù)組的訪問也是使用下標來獲取元素的,二維數(shù)組是有行和列的,只要鎖定了行和列就可以唯一鎖定數(shù)組中的某一個元素。而C語言規(guī)定,二維數(shù)組行和列的下標都是從0開始的。
示例:
int arr[3][4] = {1,2,3,4,5,6,7,8,4,5,6,7};
圖解:
示例:訪問二維數(shù)組中的元素
#include <stdio.h>
int main()
{//定義一個int類型的二維數(shù)組int arr[3][4] = {1,2,3,4,5,6,7,8,4,5,6,7};//通過行和列的下標引用操作符來定位3這個元素printf("%d\n",arr[0][2]); return 0;
}
示例:通過下標打印所有元素(二維數(shù)組的輸出)
#include <stdio.h>
int main()
{//定義一個int類型的二維數(shù)組int arr[3][4] = {1,2,3,4,5,6,7,8,4,5,6,7};//通過下標打印所有元素(數(shù)組的輸出)int i = 0;for(i=0;i<3;i++){int j = 0;for(j=0;j<4;j++){printf("%d ",arr[i][j]);}printf("\n");}return 0;
}
示例:給數(shù)組輸入自己想要的數(shù)據(jù)(二維數(shù)組的輸入)
#include <stdio.h>
int main()
{//定義一個int類型的二維數(shù)組int arr[3][4] = {1,2,3,4,5,6,7,8,4,5,6,7};//給數(shù)組輸入自己想要的數(shù)據(jù)(二維數(shù)組的輸入)int i = 0;for(i=0;i<3;i++){int j = 0;for(j=0;j<4;j++){scanf("%d",&arr[i][j]);}printf("\n");}return 0;
}
4.二維數(shù)組在內(nèi)存中的存儲
示例:依次打印二維數(shù)組中元素的內(nèi)存地址
#include <stdio.h>
int main()
{//定義一個int類型的二維數(shù)組int arr[3][4] = {1,2,3,4,5,6,7,8,4,5,6,7};//通過下標打印所有元素(數(shù)組的輸出)int i = 0;for(i=0;i<3;i++){int j = 0;for(j=0;j<4;j++){printf("&arr[%d][%d] = %p\n",i,j,&arr[i][j]);}printf("\n");}return 0;
}
從輸出結果可以看出,二維數(shù)組中每一行內(nèi)部的每個元素都是相鄰的,二維數(shù)組隨著下標的增長,地址是由低到高變化的,并且每兩個相鄰的元素之間相差為4(因為1個int
整型是4個字節(jié)),跨行位置處的兩個元素之間也是差4個字節(jié);所以得出一個結論:二維數(shù)組在內(nèi)存中是連續(xù)存放的。
5.C99
中的變長數(shù)組
在C99
標準之前,C語言在創(chuàng)建數(shù)組的時候,對于數(shù)組大小的指定只能使用常量;常量表達式,或者在初始化數(shù)據(jù)的時候去省略數(shù)組的大小,這樣的語法創(chuàng)建,讓我們在創(chuàng)建數(shù)組的時候顯得不夠靈活,有時候數(shù)組大了浪費空間,數(shù)組小了又不夠用。
示例:
//在C99之前創(chuàng)建數(shù)組的方式
int arr1[10]; //使用常量來指定數(shù)組的大小
int arr2[7+1]; //使用常量表達式來指定數(shù)組的大小
int arr3[] = {1,2,3}; //初始化數(shù)據(jù)的時候省略數(shù)組的大小
而在C99
標準中給出一個**變長數(shù)組(variable-length array 簡稱VLA
)**的新特性,允許我們可以使用變量來指定數(shù)組的大小。
示例:
//在C99之后創(chuàng)建數(shù)組的方式 -- 變長數(shù)組(允許數(shù)組的大小是變量的)
#include <stdio.h>
int main()
{int i = 0;scanf("%d",&i);int arr[i]; //變長數(shù)組是不能初始化的,會發(fā)生報錯return 0;
}
在上面的示例中,arr
就是一個變長數(shù)組,因為它的長度取決于變量i
的值,編譯器沒辦法事先確定,只有在運行時才能知道i
是多少。
- 變長數(shù)組的根本特征就是數(shù)組的長度只有在運行時才能夠確定,所以變長數(shù)組不能被初始化。
- 變長數(shù)組的好處是程序員不必在開發(fā)時,隨意為數(shù)組指定一個估計的長度,程序可以在運行時為數(shù)組分配一個精確的長度。
- 變長數(shù)組的意思是數(shù)組的大小是可以通過變量來指定的,在程序運行的時候,根據(jù)變量的大小來指定數(shù)組的元素個數(shù),而不是說數(shù)組的大小是可變的,數(shù)組的大小一旦被確定就不能再變化了
注意:
這個程序此時仍然會發(fā)生報錯,因為VS雖然支持了C99
的語法,但并不是全部支持(變長數(shù)組在VS上就是不支持的)(大家可以使用其它的編譯器試一下)
6.題目練習
示例1:編寫代碼,演示多個字符從兩端移動,同時向中間匯聚
如:
ABCDEFGHIJK
?
***********
?
A*********K
?
AB*******JK
#include <stdio.h>
#include <string.h>
#include <windows.h> //休眠函數(shù)的頭文件
int main()
{char arr1[] = "ABCDEFGHIJK";char arr2[] = "***********";int left = 0;int right = strlen(arr1) - 1;while(left<=right){arr2[left] = arr1[left];arr2[right] = arr1[right];printf("%s\n",arr2);//添加一個動態(tài)的效果,讓它運行的時候休眠1秒Sleep(1000); //休眠函數(shù),單位是毫秒//在一行上讓其向兩端移動system("cls"); //用來執(zhí)行系統(tǒng)命令的left++;right--;}//在system()全部清理完成后再打印一次完整的結果printf("%s\n",arr2);return 0;
}
示例2:二分查找
二分查找也叫做折半查找,是在一個指定的有序數(shù)組中,查找具體的一個數(shù)字n,對于這種題目,可以使用遍歷和二分查找來做,但遍歷數(shù)組相比于二分查找,效率比較低
如(1):用遍歷完成
int arr[] = {1,2,3,4,5,6,7,8,9,10};
在arr這個數(shù)組中查找到7這個數(shù)字;如果找到了就打印下標,找不到就打印找不到
#include <stdio.h> int main() {int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int n = sizeof(arr) / sizeof(arr[0]); // 計算數(shù)組長度 int target = 0; scanf("%d", &target);int found = 0; for (int i = 0; i < n; i++) {if (arr[i] == target) {printf("找到數(shù)字%d,下標為%d\n", target, i);found = 1; break;}}if (found == 0) {printf("找不到數(shù)字%d\n", target);}return 0;
}
如(2):用二分查找完成
int arr[] = {1,2,3,4,5,6,7,8,9,10};
在arr這個數(shù)組中查找到7這個數(shù)字;如果找到了就打印下標,找不到就打印找不到
#include <stdio.h>
int main()
{int arr[] = {1,2,3,4,5,6,7,8,9,10};int k = 0;int s = sizeof(arr)/sizeof(arr[0]);scanf("%d",&k);//二分查找int left = 0;int right = s - 1;int find = 0; //假設找不到while(left<=right){int mid = (left + right) / 2;if(arr[mid] < k){left = mid + 1;}else if(arr[mid] > k){right = mid - 1;}else{printf("找到了,下標是%d\n",mid);find = 1;break;}}if(find == 0){printf("找不到該元素\n");}return 0;
}
注意:
當數(shù)字過大時超出整型所能表示的最大值(INT_MAX == 2147483647)的時候,內(nèi)存會溢出,數(shù)據(jù)會出現(xiàn)錯誤
擴展:
#include <stdio.h>
int main()
{int a = 2147483647;int b = 2147483647;
// int c = (a + b) / 2; //在這種情況下數(shù)據(jù)會出現(xiàn)錯誤int c = a + (b-a) / 2; //這種方法會保證數(shù)據(jù)正常,不會出現(xiàn)問題printf("%d\n",c);return 0;
}right = mid - 1;}else{printf("找到了,下標是%d\n",mid);find = 1;break;}}if(find == 0){printf("找不到該元素\n");}return 0;
}
注意:
當數(shù)字過大時超出整型所能表示的最大值(INT_MAX == 2147483647)的時候,內(nèi)存會溢出,數(shù)據(jù)會出現(xiàn)錯誤
擴展:
#include <stdio.h>
int main()
{int a = 2147483647;int b = 2147483647;
// int c = (a + b) / 2; //在這種情況下數(shù)據(jù)會出現(xiàn)錯誤int c = a + (b-a) / 2; //這種方法會保證數(shù)據(jù)正常,不會出現(xiàn)問題printf("%d\n",c);return 0;
}