C初階2:數(shù)組

1. 初始化

1.1 整體初始化

試一下下面三段代碼跟狱,分析輸出。

  • 代碼一
int arr[12];
for(int i=0;i<12;++i){
    printf("%d ",arr[i]);
}
  • 代碼二
int arr[12] = {0};
for(int i=0;i<12;++i){
    printf("%d ",arr[i]);
}
  • 代碼三
int arr[12] = {2};
for(int i=0;i<12;++i){
    printf("%d ",arr[i]);
}

結(jié)論:

  1. 數(shù)組未初始化丧靡,數(shù)組里面的值都是隨機值祖能。
  2. 數(shù)組初始化為{0}歉秫,數(shù)組里面的值都是0
  3. 數(shù)組初始化為{非零值}养铸,數(shù)組里面第一個值是非零值雁芙,其他的值都是0

1.2 部分初始化

試一下代碼揭厚,分析輸出却特。

int arr[12] = {[2]=2,[5]=5};
for(int i=0;i<12;++i){
    printf("%d ",arr[i]);
}

指定下標的值被賦值,其他的值都是0筛圆。這是C99語法。

1.3 大小

試一下椿浓,下面代碼分析結(jié)果太援。

char carr[12];
int iarr[12];
double farr[12];
printf("carr = %d\n",sizeof(carr));
printf("iarr = %d\n",sizeof(iarr));
printf("farr = %d\n",sizeof(farr));

sizeof給出整個數(shù)組所占據(jù)的內(nèi)容的大小。數(shù)組大小=元素大小*數(shù)組個數(shù)扳碍。

問題:已知數(shù)組arr提岔,如何求出數(shù)組元素個數(shù)?

1.4 賦值

試一下下面的代碼

int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
int arr = days;

2. 數(shù)組與指針

2.1 數(shù)組名是地址

數(shù)組名是數(shù)組第一個元素的地址笋敞。

int arr[] = {1,2,3,4,5,6,7,8};
printf("&arr=%p\n",&arr);
printf("arr=%p\n",arr);
printf("&arr[0]=%p\n",&arr[0]);

數(shù)組下標實現(xiàn)的操作指針也可以實現(xiàn)碱蒙。數(shù)組名+下標表示下標i元素的地址。

No. 操作 下標 指針
1 i個元素值 arr[i] *(arr+i)
2 i個元素地址 &arr[i] arr+i

所以夯巷,遍歷數(shù)組可以是

int arr[] = {1,2,3,4,5,6,7,8};
for(int i=0;i<8;++i){
    printf("%d\n",*(arr+i)); 
}

數(shù)組名是不可改變的赛惩。

int arr1[] = {1,2,3,4,5,6,7,8};
int arr2[] = {1,2,3,4,5,6,7,8};
arr2 = arr1

數(shù)組下標比較易于理解,數(shù)組指針更靈活更高效趁餐。
要點

  1. 數(shù)組名是數(shù)組第一個元素的地址喷兼。
  2. 數(shù)組名+下標表示下標i元素的地址。
  3. 數(shù)組名是不可改變的后雷。

2.2 數(shù)組名放入指針

地址存儲在指針中季惯。可以用指針操作地址臀突。

int arr[] = {1,2,3,4,5,6,7,8};
int* p = arr;
for(int i=0;i<8;++i){
    printf("%d\n",*(p+i)); 
}

3. 函數(shù)與數(shù)組

3.1 傳遞數(shù)組給函數(shù)

數(shù)組作為函數(shù)參數(shù)時勉抓,通常必須再用一個參數(shù)傳入數(shù)組大小。

返回值類型 函數(shù)名(類型 參數(shù)名[],int size){

}

或者

返回值類型 函數(shù)名(類型* 參數(shù)名,int size){

}

例如:打印數(shù)組元素

#include <stdio.h>

void PrintArr1(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void PrintArr2(int* arr,int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int main(){
    int arr[] = {1,2,3,4,5,6,7,8,9};
    PrintArr1(arr,9);
    PrintArr1(arr,3);
    PrintArr1(arr+6,3);
    PrintArr1(arr+3,3);
}

試一下下面代碼

#include <stdio.h>

void Test1(int a[]){
    printf("sizeof(a):%d\n",sizeof(a));
    printf("a:%p\t&a:%p\n",a,&a);
}
void Test2(int* p){
    printf("sizeof(p):%d\n",sizeof(p));
    printf("p:%p\t&p:%p\n",p,&p);
}
int main(){
    int arr[10];
    printf("sizeof(arr):%d\n",sizeof(arr));
    printf("arr:%p\t&arr:%p\n",arr,&arr);
    Test1(arr);
    Test2(arr);
}

數(shù)組作為參數(shù)時候学,數(shù)組退化成指針藕筋,不能利用sizeof獲取數(shù)組大小,也就不能計算數(shù)組元素個數(shù)盒齿。

3.2 從函數(shù)返回數(shù)組

C 語言不允許返回一個完整的數(shù)組作為函數(shù)的參數(shù)困食。通過指定不帶索引的數(shù)組名來返回一個指向數(shù)組的指針。

類型* 函數(shù)名() {
   return 數(shù)組名;
}

練習

  1. 給定數(shù)組隨機填充指定范圍的數(shù)據(jù)翎承。
    使用stdlib.h中的srand(time(NULL))rand()硕盹。
  2. 將一維數(shù)組的查找FindArr()、替換Replace()封裝成函數(shù)叨咖。

FindArr()可以返回bool(有無)瘩例、int(下標)、int*(地址)有什么區(qū)別甸各。

  • 返回值含義(返回值的含義以及值是人為定義的)
    返回值有時存在兩種情況:合法值和非法值垛贤。
    如果有非法值的情況,通常使用一些特定的值指代特殊情況趣倾。例如:數(shù)組下標只能是0和正數(shù)聘惦。我們實現(xiàn)數(shù)組查找元素下標時,存在找不到元素的情況儒恋,這時善绎,使用-1可以作為這種情況的返回值。

重點

int arr[] = {1,2,3,4,5,6};
// sizeof(數(shù)組名)
printf("sizeof(arr) = %ld\n",sizeof(arr));
// 數(shù)組名的值
printf("arr=%p\n&arr[0]=%p\n",arr,&arr[0]);

數(shù)組名是地址诫尽,是常量禀酱。

  1. 可以使用指針操作:解引用
  2. 數(shù)組作為函數(shù)參數(shù)和返回值時,傳指針/地址牧嫉。

數(shù)組下標與數(shù)組長度的關(guān)系

  1. arr長度為n剂跟,最后一個元素的下標為n-1
  2. 下標為i是第i+1個元素酣藻,前面有i個元素(不包含i)曹洽,后面有n-(i+1)個元素(不包含i)。
  3. 下標i和j之間有j-i個元素(包含i臊恋,不包含j)

數(shù)組地址與數(shù)組名的關(guān)系

  1. 數(shù)組arr的首地址為arr衣洁,下標為i的地址為arr+i
  2. p=arr+i,那么下標對應(yīng)為p-arr抖仅。
  3. p前面有p-arr個元素(不包含p)坊夫,后面有n-(p-arr+1)個元素(不包含p)。

4. 多維數(shù)組

4.1 聲明

  • 語法
類型 數(shù)組名[元素個數(shù)1][元素個數(shù)2]...[元素個數(shù)N];

多維數(shù)組最常用形式是二維數(shù)組撤卢。二維數(shù)組相當于一個行列組成的表环凿。

類型 二維數(shù)組名[行數(shù)][列數(shù)];

例如下面是一個43列元素類型為int的表。

int days[4][3];

4.2 初始化二維數(shù)組

多維數(shù)組可以通過在括號內(nèi)為每行指定值來進行初始化放吩。

int days[4][3]={
    {31,28,31},
    {30,31,30},
    {31,31,30},
    {31,30,31}
};

4.3 訪問二維數(shù)組元素

二維數(shù)組中的元素是通過使用下標(即數(shù)組的行索引和列索引)來訪問的智听。


// 獲取一月份的天數(shù)
int n = days[0][0];
// 修改二月份的天數(shù)
days[0][1] = 29;
// 打印一月份天數(shù)
printf("%d",days[0][0]);

4.4 二維數(shù)組元素遍歷

通常使用嵌套循環(huán)來處理二維數(shù)組。

for (int i = 0; i < 4; i++ ) {
    for (int j = 0; j < 3; j++ ) {
       printf("a[%d][%d] = %d\n",i,j,a[i][j]);
    }
}

4.5 二維數(shù)組輸入

int n,m;
scanf("%d%d",&n,&m);
int arr[n][m];
for (int i=0;i<n;++i){
  for (int j=0;j<m;++j){
      scanf("%d",&arr[i][j]);
  }
}

練習

  1. 輸入m個學生的n門課程成績,輸出各門課程成績以及總成績和平均值到推。

  2. 二維數(shù)組通晨既可用于表示數(shù)學中的矩陣。實現(xiàn)矩陣基本運算(加法莉测、減法颜骤、乘法、轉(zhuǎn)置)捣卤。


  3. mn月的日期忍抽,按星期以日歷方式放入二維數(shù)組(列表示星期),并打印出來董朝。

4.6 簡化

初始化二維數(shù)組可以有如下簡化寫法:

  1. 省略內(nèi)部嵌套括號鸠项。
int days[4][3]={31,28,31,30,31,30,31,31,30,31,30,31};
  1. 省略第一維大小,第二維不能省略子姜。
int days[][3]={31,28,31,30,31,30,31,31,30,31,30,31};

問題
二維數(shù)組可以整體初始化嗎祟绊?
練習

4.7 二維數(shù)組作為函數(shù)參數(shù)

二維數(shù)組作為函數(shù)參數(shù),需要同屬輸入行和列的個數(shù)闲询。

void PrintMatrix(int m[4][3],int r,int c)
for (int i = 0; i < r; i++ ) {
    for (int j = 0; j < c; j++ ) {
       printf("%d\n",m[i][j]);
    }
}

4.8 多維數(shù)組

大于二維的數(shù)組的用法與二維數(shù)組一樣久免,只是使用比較少。

int days[][4][3]={
    {31,28,31,30,31,30,31,31,30,31,30,31}, // 平年
    {31,29,31,30,31,30,31,31,30,31,30,31}  // 閏年
};

printf("平年二月天數(shù)為%d\n",days[0][0][1]);// 平年第一季度第二個月
printf("閏年二月天數(shù)為%d\n",days[1][0][1]);// 閏年第一季度第二個月 

多維數(shù)組初始化只能第一個維度可以省略扭弧。

5 const數(shù)組

5.1 const數(shù)組是什么?

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

數(shù)組變量已經(jīng)是const指針记舆,表示數(shù)組中的每一個元素都是const int鸽捻,即每個元素不能通過arr改變。
例如:

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

5.2 const數(shù)組怎么用泽腮?

保護數(shù)組值

因為數(shù)組作為函數(shù)參數(shù)是以地址方式傳遞的御蒲,所以函數(shù)內(nèi)部可以修改數(shù)組的值。
為了保護數(shù)組不被函數(shù)破壞诊赊,可設(shè)置參數(shù)為const厚满。
例如:

int sum(const int arr[],int len);

或者

int sum(const int* arr,int len);

6 變量指針 vs 數(shù)組指針

變量指針:指向單個變量的指針。
數(shù)組指針:指向數(shù)組的指針碧磅。

#include <stdio.h>

int main () {
    int n = 10;
    int *p;
    p = &n; // p指針指向變量
    printf("*p = %d\n",*p);
    
    int arr[] = {1,2,3,4,5,};
    p = arr;// p指針指向數(shù)組
    printf("*p = %d\n",*p);
    printf("*(p+1) = %d\n",*(p+1));
    printf("*(p+2) = %d\n",*(p+2));
    printf("*(p+3) = %d\n",*(p+3));
    printf("*(p+4) = %d\n",*(p+4));
    
    return 0;
}

指針既可以指向一個基本類型變量又可以指向一個數(shù)組碘箍。所以在使用時要注意分辨。

7 項目

輸入年份打印萬年歷鲸郊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丰榴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秆撮,更是在濱河造成了極大的恐慌四濒,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盗蟆,居然都是意外死亡戈二,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門喳资,熙熙樓的掌柜王于貴愁眉苦臉地迎上來觉吭,“玉大人,你說我怎么就攤上這事骨饿】髡唬” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵宏赘,是天一觀的道長绒北。 經(jīng)常有香客問我,道長察署,這世上最難降的妖魔是什么闷游? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮贴汪,結(jié)果婚禮上脐往,老公的妹妹穿的比我還像新娘。我一直安慰自己扳埂,他們只是感情好业簿,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阳懂,像睡著了一般梅尤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岩调,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天巷燥,我揣著相機與錄音,去河邊找鬼号枕。 笑死缰揪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的葱淳。 我是一名探鬼主播钝腺,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛙紫!你這毒婦竟也來了拍屑?” 一聲冷哼從身側(cè)響起谈宛,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤扛禽,失蹤者是張志新(化名)和其女友劉穎备禀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體持痰,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溪厘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年洋机,在試婚紗的時候發(fā)現(xiàn)自己被綠了疆栏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡粉私,死狀恐怖顽腾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诺核,我是刑警寧澤抄肖,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站窖杀,受9級特大地震影響漓摩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜入客,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一管毙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桌硫,春花似錦夭咬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膀钠,卻和暖如春边器,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背托修。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恒界,地道東北人睦刃。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像十酣,于是被迫代替她去往敵國和親涩拙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 教育心理學是一門研究學校內(nèi)外學生的發(fā)展、學習虾宇、動機搓彻、教學與評估的學科。 1、教師效能感:由于大眾媒體的影...
    蘊韻1236閱讀 215評論 0 6
  • 小編最近補看了歡樂喜劇人扼脐,節(jié)目段子各種搞笑!但是更迷上了這個煤炭一樣黑的男人有沒有7芄簟瓦侮! ...
    慢慢狂奔閱讀 9,741評論 0 0
  • 互聯(lián)網(wǎng)+醫(yī)療行業(yè),會孕育大量的醫(yī)療健康服務(wù)創(chuàng)業(yè)公司佣谐,在醫(yī)生肚吏、患者、醫(yī)院台谍、醫(yī)藥须喂、單科領(lǐng)域、智能硬件趁蕊、醫(yī)療新媒體等領(lǐng)域...
    阿柯瑪?shù)氐?/span>閱讀 263評論 0 0
  • 1坞生、描述:名字《明天》 2、順序: 房子一路一花草一右側(cè)樹一左側(cè)樹一云朵一小鳥一人物(我掷伙,女兒是己,老公)本來畫的火柴...
    淘伊_心向光明閱讀 359評論 6 1
  • #玩卡不卡·每日一抽#每一位都可以通過這張卡片覺察自己: 1、直覺他叫什么名字任柜?保羅 2卒废、他幾歲了?40 3宙地、他現(xiàn)...
    我心安住閱讀 130評論 0 0