數(shù)組_C語言

定義

數(shù)組就是相同數(shù)據(jù)類型構(gòu)成的一組數(shù)

數(shù)組名

  • 數(shù)組名的值是一個指針常量(你不能修改常量的值),它是數(shù)組第一個元素的地址,他的類型取決于數(shù)組元素的類型
  • 數(shù)組和指針是不一樣的,數(shù)組具有確定數(shù)量的元素,而指針只是個標(biāo)量值
  • 指針常量所指向的是內(nèi)存中數(shù)組的起始位置,如果修改這個指針常量,唯一可行的方法就是把整個數(shù)組移動到內(nèi)存的其他位置

只有在兩種場合下,數(shù)組名并不用指針常量來表示

  1. 當(dāng)數(shù)組名作為sizeof操作符,sizeof返回整個數(shù)組的長度,而不是指向數(shù)組的指針的長度
  2. 單目操作符&的操作數(shù)時,取一個數(shù)組名的地址所產(chǎn)生的是一個指向數(shù)組的指針,而不是指向某個指針常量值得指針

這兩者是等價的

int a[10];

int *c;
c = &a[0];
c = a;

初始化

類型標(biāo)識符 + 數(shù)組名 + 數(shù)組元素的個數(shù)(常量表達(dá)式) + 初始值

int arr[5] = {0};
  • excess element 超過 數(shù)組越界
    數(shù)組元素不要超過給定的,數(shù)組越界有可能導(dǎo)致程序崩潰
    中括號中數(shù)組的元素的個數(shù)
  • 不能放變量
int arr6[4] = {1,2,3,4,5};
int i = 10;

int arr1[i] = {0};

int arr1[8 + 2] = {0};

int arr2[] = {1,2,3};// 不建議

float arr3[3] = {1.0,2.0,3.0};

double arr4[3] = {2.0,3.0,4.023123};

long arr5[4] = {5345,64563,234};

指針 和 下標(biāo)

下標(biāo)

下標(biāo)和數(shù)組名一起使用,用于標(biāo)識該集合中某個特定的值

int b[10];
*(b+3);

b的值是一個指向整型的指針,*(b+3)所指向的是數(shù)組的第1個元素向后移3個整數(shù)長度的位置,然后間接訪問這個新的位置

除了優(yōu)先級之外,下標(biāo)引用和間接訪問完全相同

array[subscript];
*(array+(subscript));

關(guān)于下標(biāo)和指針的理解

int array[10];
int *ap = array +2;
指針 轉(zhuǎn)換 下標(biāo)
ap array + 2 &array[2]
*ap *(array + 2) array[2]
ap[0] *(ap+(0)) = array + 2 &array[2]
ap+6 array + 2 + 6 = array + 8 &array[8]
*ap+6 *(array + 2) + 6 array[2]+6
*(ap+6) *(array 2 + 6) array[8]
ap[6] *(ap+(6)) &array[8]
&ap ap指針?biāo)诘牡刂?/td>
ap[-1] *(array+(-1)) array[1]

2[array]相當(dāng)于*(2+(array))也就是說*(array+2)

  • 有些編譯器會有下標(biāo)檢查,但這是一個不小的負(fù)擔(dān),不過對于如今的電腦而言,并不是個大的問題
  • 指針有時候會比下標(biāo)更有效率,但不應(yīng)因為效率而影響程序的可讀性

一般有數(shù)組的地方就有循環(huán)

遍歷一個數(shù)組 數(shù)組下標(biāo),從0開始到 數(shù)組元素個數(shù)-1 為止

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

數(shù)組 和 指針

  • 聲明一個數(shù)組時,編譯器將根據(jù)聲明所指定的元素數(shù)量為數(shù)組元素保留內(nèi)存空間,然后在創(chuàng)建數(shù)組名,它的值是一個常量,指向這段空間的起始位置.
  • 聲明一個指針變量時,編譯器只為指針變量保存內(nèi)存空間,如果它是一個自動變量,它甚至根本不會被初始化
int a[5];
int *b;

上述聲明后

  • 表達(dá)式*a是完全合法的,但表達(dá)式*b是非法的
  • *b將訪問內(nèi)存中某個不確定的位置,或者導(dǎo)致程序終止
  • b++能通過編譯,但a++卻不能,因為a的值是一個常量

作為函數(shù)參數(shù)的數(shù)組名

當(dāng)數(shù)組名作為參數(shù)傳遞給函數(shù)時是指向數(shù)組第一個元素指針的拷貝,函數(shù)如果執(zhí)行了下標(biāo)引用,實(shí)際上是對這個指針執(zhí)行間接訪問操作,函數(shù)可以訪問和修改調(diào)用程序的數(shù)組元素

以下兩個聲明只是在當(dāng)前這個上下文環(huán)境中相等

int fun(char *string);
int fun(char string[]);

字符數(shù)組 和 字符串

字符數(shù)組

char arr[4] = {'a','n','s','d'};
char arr[4] = "ansd";

以下聲明,盡管第二個聲明看像去是一個字符串常量,實(shí)際上并不是

char message[] = "Hello";
char *message2 = "Hello";

以上聲明

  • 前者初始化一個字符數(shù)組的元素
  • 后者是一個真正的字符串常量,這個指針變量被初始化為指向這個字符串常量的存儲位置

輸出方法

for (int i = 0; i < 4; i++) {
    printf("%d\t",arr[i]);
    printf("%c\t\n",arr[i]);
}

多維數(shù)組

初始化

// 方法一
int matrix[2][3] = {100,101,102,110,111,112};
// 方法二
matric[0][2] = 102;
// 方法三
int matix2[3][5]={
    {00,01,02,03,04},
    {10,11,12,13,14},
    {20,21,22,23,24}
}

存儲順序

int a[12];
int b[3][4];
int c[2][2][3];
數(shù)值 int a[12]; int b[3][4]; int c[2][2][3];
0 a[0] b[0][0] c[0][0][0]
1 a[1] b[0][1] c[0][0][1]
2 a[2] b[0][2] c[0][0][2]
3 a[3] b[0][3] c[0][1][0]
4 a[4] b[1][0] c[0][1][1]
5 a[5] b[1][1] c[0][1][2]
6 a[6] b[1][2] c[1][0][0]
7 a[7] b[1][3] c[1][0][1]
8 a[8] b[2][0] c[1][0][2]
9 a[9] b[2][1] c[1][1][0]
10 a[10] b[2][2] c[1][1][1]
11 a[11] b[2][3] c[1][1][2]
// 給數(shù)組a賦值
    int *d = a;
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
// 給數(shù)組b賦值
    d = &b[0][0];
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
// 給數(shù)組c賦值
    d = **C;
    for (int i = 0; i < 12; i++)
    {
        *d = i;
        d++;
    }
    // 打印數(shù)組a
    for (int i = 0; i < 12; i++)
    {
        cout << "a"<<i<<"="<<a[i] << endl;
        // printf("a[%d] = %d \n", i,a[i]);
    }
    // 打印數(shù)組b
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << "b" << i << j <<"=" << b[i][j] << endl;
        }   
    }
    // 打印數(shù)組c
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            for (int k = 0; k < 3; k++)
            {
                cout << "c" <<i<<j<<k<<"=" <<c[i][j][k] << endl;
            }
        }
    }

數(shù)組名

  • 一維數(shù)組名得值是一個指針常量,類型:指向元素類型的指針,它指向數(shù)組的1個元素
  • 二維數(shù)組名的值是一個指向一個包含x個某類型元素的數(shù)組的指針
int matrix[2][3];
  • matrix; 類型:指向包含3個整形元素的數(shù)組的指針
  • *matrix; 類型:指向整形的指針

下標(biāo)

array[s2][s1];
*(*(array+(s1))+(s2));

注意:

array[3,4];

相當(dāng)于

array[4];

逗號操作符首先對第1個表達(dá)式求值,但隨即丟棄這個值,最后的結(jié)果是第2個表達(dá)式的值

指向數(shù)組的指針

對于一維數(shù)組,以下聲明是合法的

int vector[10],*vp = vector;

但對于多維數(shù)組,以下聲明則是非法的

int matrix[3][10],*mp = matrix;

因為matrix并不是一個指向整形的指針,而是一個指向整形數(shù)組的指針,其指針聲明如下

int (*)p[10];

下標(biāo)的引用的優(yōu)先級高于間接訪問,但由于括號的存在,首先執(zhí)行的還是間接訪問,接下來執(zhí)行的是下標(biāo)引用,所以p指向的是某種類型的數(shù)組,對該數(shù)組進(jìn)行下標(biāo)引用操作得到的是一個整型值,所以p是一個指向整型數(shù)組的指針

int (*p)[10] = matrix;

它使p指向matrix的第一行,p是一個指向擁有10個整形元素的數(shù)組指針
如果需要一個指針逐個訪問整型元素可以進(jìn)行如下聲明

int *pi = &matrix[0][0];
int *pi = matrix[0];

作為參數(shù)的多維數(shù)組

其實(shí)際傳遞的是指向數(shù)組第一個元素的指針,多維數(shù)組的每個元素本身是另外一個數(shù)組,編譯器需要知道它的維數(shù),以便為函數(shù)形參的下標(biāo)表達(dá)式求值

int matrix[3][10];
fun(matrix);

參數(shù)matrix的類型是指向包含10個整形元素的數(shù)組的指針

fun的函數(shù)原型如下

void fun(int (*mat)[10]);
void fun(int mat[][10]);

數(shù)組長度自動計算

對于多維數(shù)組,只有第一維才能根據(jù)初始化列表缺省地提供,其他幾個維度必須顯式地寫出

指針數(shù)組

int *api[10];
  • 下標(biāo)引用高于間接訪問,所以在這個表達(dá)式中,首先執(zhí)行下標(biāo)引用,因此api是某類型的數(shù)組,其元素個數(shù)為10
  • 隨后進(jìn)行間接訪問操作,得到一個整形,所以其元素類型為指向整形的指針

例:

以下為一個指針數(shù)組

char const keyword[]={
    "do",
    "for",
    "if",
    "register",
    "return";
    "switch"
    "while"
};
#define N_KEYWORD (sizeof(keyword)/sizeof(keyword[0]))

以下則為一個矩陣

char const keyword[][9]={
    "do",
    "for",
    "if",
    "register",
    "return";
    "switch"
    "while"
};

sizeof用于對數(shù)組中的元素進(jìn)行自動計數(shù)

  • 通過sizeof來得到數(shù)組中元素的個數(shù)
  • sizeof(keyword)的結(jié)果為整個數(shù)組所占用的字節(jié)數(shù)
  • sizeof(keyword[0])為數(shù)組每個元素所占用的字節(jié)數(shù)
  • 這兩個數(shù)相除為整個數(shù)組的個數(shù)

sizeof是字符的大小

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

sizeof(a) / sizeof(int) 數(shù)據(jù)大小 / 數(shù)據(jù)類型大小 = 多少個

數(shù)組:排序 冒泡排序

冒泡排序是一個雙層的for循環(huán) ,外層循環(huán)控制的是比較的趟數(shù),內(nèi)層循環(huán)控制的是每次比較的次數(shù)

   int arr6[5] = {6,5,4,3,1};
   for(int i = 0; i < 5 - 1; i++) {
       for(intj = 0; j < 5 - i - 1; j++) {
           if(arr6[j] > arr6[j+1]) {
                arr6[j] = arr6[j] ^ arr6[j+1];
                arr6[j+1] = arr6[j] ^ arr6[j+1];
                arr6[j] = arr6[j] ^ arr6[j+1];
            }
        }
    }
   for(int i = 0; i < 5; i++) {
       printf("arry5[%d] is %d\n",i,arr6[i]);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 一、框架 1、Mac系統(tǒng)及常用工具、進(jìn)制;C數(shù)據(jù)類型、常量變量、運(yùn)算符、表達(dá)式、格式化輸入輸出 2、關(guān)系運(yùn)算符、邏...
    師景福閱讀 735評論 0 2
  • C語言大總結(jié) 一、基礎(chǔ): 1、進(jìn)制、位權(quán)、1字節(jié)等于8位(位是計算機(jī)的最小儲存單位,字節(jié)是計算機(jī)最小存儲單元)、十...
    霧中探雪閱讀 2,862評論 1 36
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,540評論 1 51
  • 不覺已近三月末,有多少人還在春困還在沉溺于春日暖陽。然而從開學(xué)來,這座南方城市鮮有陽光,同學(xué)們戲稱自從追了太陽的后...
    炸雞小公舉閱讀 156評論 0 0
  • 每一個人 都像是一棵樹 沒有一樣的 每一處森林 散發(fā)的氣息 就如同我們居落的村莊 構(gòu)成千姿百態(tài)的生活方式 只是有大...
    蔡振源閱讀 541評論 0 5