Linux_C編之(4)數組

數組

變量在內存存放是有地址的,數組在內存存放也同樣具有地址。對於數組來說,數組名就是數組在內存中存放的數組首元素的地址。

(一)數組認知

C語言對屬組的處理是非常有效的
原因有以下三點:
(1)除了少數編譯器處於謹慎會做出一些繁瑣的規定外,C語言的數組下標是在一個很低的層次上處理的。但是這個優點也有一個反作用,即在程序運行時你無法知道 一個數組到底有多大或者一個數組的下標是否有效。
對一個越界的下標可能導致以下幾種後果:

  • 程序仍然能正常運行
  • 程序會異常終止或者崩潰
  • 程序能繼續運行,但是無法獲得正確的結果
  • 其他情況

(2)數組和指針能非常和諧地在一起工作,當數組出現在一個表達式中,它和指向數組中第一個元素的指針是等價的,因此數組和指針幾乎可以互換使用,此外,使用指針要比使用數組下標快兩倍。
將數組作爲參數傳遞給函數和將指向數組中第一個元素的指針傳遞給函數是完全等價的,將數組作爲參數傳遞給函數時可以採用值傳遞和地址傳遞兩種方式,前者需要完整地複製初始數組,但比較安全;後者的速度要快得多。
數組和指針之間的這種聯繫會引起一些混亂,例如,一下兩種定義是完全相同的:

void func(char a[max])
 {}
void func(char *a)
{
	;
}

(3)

char a[MAX];

系統將分配MAX個字符的內存空間

cahr *a;

系統將分配一個字符指針所需要的的內存空間,可能只能容納2個或者4個字符

定義函數

char a[MAX];

聲明卻是這樣聲明

extern char *a;

就會報錯

(二)使用數組之常見問題

(1)、數組的下標總是從0開始嗎
是的,對數組a[MAX]來說,它的第一個和最後一個元素分別是a[0]和a[MAX-1]。注意:a[MAX]是一個有效的地址,但是地址中的值並不是數組a中的一個元素。
數組下標從0開始的原因: 指針和數組幾乎是相同的,因此你可以定義一個指針,使它可以像一個數組一樣引用另一個數組中的所有元素,但是引用前者的下標是從1開始的。

int a0[MAX];
int *a1=a0-1;

現在a0[0]和a1[1]是相同的,而a0[MAX-1]和a1[MAX]也是相同的。然而在實際編程中不應該這麼做,因爲:

  1. 這種方法可能行不通,這種行爲是ANSI/ISO C 標準中沒有定義的,而&a0[-1]完全可能是一個無效的地址。
  2. 違背了C語言的常規風格,別人很難讀懂你的程序,可讀性太差

(2)、可以使用數組後面第一個元素的地址嗎
在這裏插入圖片描述
輸出爲1,說明確實可以用後面的地址

(3)爲什麼要小心對待位於數組後面的那些元素的地址呢
程序在計算機上運行,它的取址範圍是00000000-FFFFFFFF。
但是在有些計算機上,地址是由兩部分組成的,第一部分是一個指向某一塊內存的起始點的指針(即基地址),第二部分是相對於這塊內存的起始點的地址偏移量。這種地址被稱爲段地址結構,通常子程序的調用就是通過在棧指針上加上一個地址偏移量來實現的。如果基地址無法改變,而偏移量也不可能是個負值,所以位於a[0]前面的就沒有意義了。同樣,最後的也沒有意義了。

(三)總結

1.一維數組的創建和初始化
數組的創建:在創建數組時,我們必須定義數組的類型和大小,數組的大小不能爲0,數組中的元素類型都是相同的。
eg:

int arr[10];//[]內必須是常量/常量表達式(3+8),不能是一個變量(x…)
1
數組的初始化:在數組創建時,我們也要必須爲數組初始化。
eg:

int arr1[3] = {1, 2, 3};
int arr2[] = {1, 2, 3};//在這裏,我們arr[3]裏邊的數字可以不用寫;
int arr3[3] = {1, 2};//也是可以的,只是把最後一個數初始化爲0了而已
int arr4[3] = {1, 2, 3, 4};//是不可以的,不能超過數組長度  
char arr5[3] = {'a', 98, 'c'};//因爲是字符類型,所以98其實就是字符'b'
char arr6[] = "abcdef";
#include<stdio.h>

int main()
{
    char arr1[] = { 'a', 'b', 'c' };
    char arr2[3] = "abc";
    char *p = "abc";//這裏只是把a的地址放進了p裏邊

    return 0; 
}

2.一維數組的使用
eg:

#include<stdio.h>

int main()
{
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0; i < 10; i++)//i<11是不可以的,不可以越界訪問
    {
        arr[i] = i;
    }

    return 0; 
}

數組是使用下標來訪問的,下標是從0開始。
數組的大小可以通過計算得到。(sz = sizeof(arr)/sizeof(arr[0]));

3.一維數組在內存中的存儲
eg:

#include<stdio.h>

int main()
{
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    {
        printf("&arr[%d] = %p\n", i, &arr[i]);
    }

    return 0; 
}
  1. 二維數組的創建和初始化
    eg:
#include<stdio.h>

int main()
{
    int arr[3][4] = { 1, 2, 3, 4, 5, 6 };
    //int arr[][4] = {{1, 2},{3, 4, 5},{6}};可以
    //arr[3][] = {{1, 2},{3, 4, 5},{6}};是不可以的

    return 0; 
}
  1. 二維數組的使用
    二維數組的使用也是通過下標方式
    eg:
#include<stdio.h>

int main()
{
    int arr[3][5] = { 0 };
    int i = 0;
    int j = 0;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 5; j++)
        {
            arr[i][j] = i * 5 + j + 1;
        }
    }

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


    return 0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章