作用域
任何一種編程中,作用域是程式中定義的變數所存在的區域,超過該區域變數就不能被訪問,C 語言中有三個地方可以宣告變數:
- 在函式或塊內部的區域變數
- 在所有函式外部的全域變數
- 在形式引數的函式引數定義中
區域變數
在某個函式或塊的內部宣告的變數稱為區域變數,它們只能被該函式或該代碼塊內部的陳述句使用,區域變數在函式外部是不可知的,
全域變數
全域變數是定義在函式外部,通常是在程式的頂部,全域變數在整個程式生命周期內都是有效的,在任意的函式內部能訪問全域變數,
全域變數可以被任何函式訪問,也就是說,全域變數在宣告后整個程式中都是可用的,
在程式中,區域變數和全域變數的名稱可以相同,但是在函式內,如果兩個名字相同,會使用區域變數值,全域變數不會被使用,
形式引數
函式的引數,形式引數,被當作該函式內的區域變數,如果與全域變數同名它們會優先使用,
全域變數與區域變數在記憶體中的區別:
- 全域變數保存在記憶體的全域存盤區中,占用靜態的存盤單元;
- 區域變數保存在堆疊中,只有在所在函式被呼叫時才動態地為變數分配存盤單元,
更多內容可參考:C/C++ 中 static 的用法全域變數與區域變數
初始化區域變數和全域變數
當區域變數被定義時,系統不會對其初始化,您必須自行對其初始化,定義全域變數時,系統會自動對其初始化,如下所示:
| 資料型別 | 初始化默認值 |
|---|---|
| int | 0 |
| char | '\0' |
| float | 0 |
| double | 0 |
| pointer | NULL |
正確地初始化變數是一個良好的編程習慣,否則有時候程式可能會產生意想不到的結果,因為未初始化的變數會導致一些在記憶體位置中已經可用的垃圾值,
陣列
C 語言支持陣列資料結構,它可以存盤一個固定大小的相同型別元素的順序集合,陣列是用來存盤一系列資料,但它往往被認為是一系列相同型別的變數,陣列中的特定元素可以通過索引訪問,
所有的陣列都是由連續的記憶體位置組成,最低的地址對應第一個元素,最高的地址對應最后一個元素,
宣告陣列
在 C 中要宣告一個陣列,需要指定元素的型別和元素的數量,如下所示:
type arrayName [ arraySize ];
這叫做一維陣列,arraySize 必須是一個大于零的整數常量,type 可以是任意有效的 C 資料型別,例如,要宣告一個型別為 double 的包含 10 個元素的陣列 balance,宣告陳述句如下:
double balance[10];
現在 balance 是一個可用的陣列,可以容納 10 個型別為 double 的數字,
初始化陣列
在 C 中,您可以逐個初始化陣列,也可以使用一個初始化陳述句,如下所示:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括號 { } 之間的值的數目不能大于我們在陣列宣告時在方括號 [ ] 中指定的元素數目,
如果您省略掉了陣列的大小,陣列的大小則為初始化時元素的個數,因此,如果:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
您將創建一個陣列,它與前一個實體中所創建的陣列是完全相同的,下面是一個為陣列中某個元素賦值的實體:
balance[4] = 50.0;
上述的陳述句把陣列中第五個元素的值賦為 50.0,所有的陣列都是以 0 作為它們第一個元素的索引,也被稱為基索引,陣列的最后一個索引是陣列的總大小減去 1,
訪問陣列元素
陣列元素可以通過陣列名稱加索引進行訪問,元素的索引是放在方括號內,跟在陣列名稱的后邊,
C 中陣列詳解
在 C 中,陣列是非常重要的,我們需要了解更多有關陣列的細節,下面列出了 C 程式員必須清楚的一些與陣列相關的重要概念:
| 概念 | 描述 |
|---|---|
| 多維陣列 | C 支持多維陣列,多維陣列最簡單的形式是二維陣列, |
| 傳遞陣列給函式 | 您可以通過指定不帶索引的陣列名稱來給函式傳遞一個指向陣列的指標, |
| 從函式回傳陣列 | C 允許從函式回傳陣列, |
| 指向陣列的指標 | 您可以通過指定不帶索引的陣列名稱來生成一個指向陣列中第一個元素的指標, |
多維陣列
多維陣列宣告的一般形式如下:
type name[size1][size2]...[sizeN];
例如,下面的宣告創建了一個三維 5 . 10 . 4 整型陣列:
int threedim[5][10][4];
二維陣列
一個二維陣列,在本質上,是一個一維陣列的串列,宣告一個 x 行 y 列的二維整型陣列,形式如下:
type arrayName [ x ][ y ];
一個二維陣列可以被認為是一個帶有 x 行和 y 列的表格,下面是一個二維陣列,包含 3 行和 4 列:
int x[3][4];

初始化二維陣列
多維陣列可以通過在括號內為每行指定值來進行初始化,下面是一個帶有 3 行 4 列的陣列,
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引號為 0 的行 */
{4, 5, 6, 7} , /* 初始化索引號為 1 的行 */
{8, 9, 10, 11} /* 初始化索引號為 2 的行 */
};
內部嵌套的括號是可選的,下面的初始化與上面是等同的:
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
訪問二維陣列元素
二維陣列中的元素是通過使用下標(即陣列的行索引和列索引)來訪問的,例如:
int val = a[2][3];
上面的陳述句將獲取陣列中第 3 行第 4 個元素,
下面的程式,我們將使用嵌套回圈來處理二維陣列:
#include <stdio.h>
int main ()
{
/* 一個帶有 5 行 2 列的陣列 */
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;
/* 輸出陣列中每個元素的值 */
for ( i = 0; i < 5; i++ )
{
for ( j = 0; j < 2; j++ )
{
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}
return 0;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
a[0][0] = 0
a[0][1] = 0
a[1][0] = 1
a[1][1] = 2
a[2][0] = 2
a[2][1] = 4
a[3][0] = 3
a[3][1] = 6
a[4][0] = 4
a[4][1] = 8
傳遞陣列給函式
如果您想要在函式中傳遞一個一維陣列作為引數,您必須以下面三種方式來宣告函式形式引數,這三種宣告方式的結果是一樣的,因為每種方式都會告訴編譯器將要接收一個整型指標,同樣地,您也可以傳遞一個多維陣列作為形式引數,
方式 1
形式引數是一個指標:
void myFunction(int *param)
{
}
方式 2
形式引數是一個已定義大小的陣列:
void myFunction(int param[10])
{
}
方式 3
形式引數是一個未定義大小的陣列:
void myFunction(int param[])
{
}
就函式而言,陣列的長度是無關緊要的,因為 C 不會對形式引數執行邊界檢查,
從函式回傳陣列
C 語言不允許回傳一個完整的陣列作為函式的引數,但是,您可以通過指定不帶索引的陣列名來回傳一個指向陣列的指標,可以先跳過本章,等了解了 C 指標的概念之后,再來學習這里的內容,
如果您想要從函式回傳一個一維陣列,您必須宣告一個回傳指標的函式,如下:
int * myFunction()
{
}
另外,C 不支持在函式外回傳區域變數的地址,除非定義區域變數為 static 變數,
下面的函式,它會生成 10 個亂數,并使用陣列來回傳它們,請注意其中包含了標準庫的函式,具體如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 要生成和回傳亂數的函式 */
int * getRandom( )
{
static int r[10];
int i;
/* 設定種子 */
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
printf( "r[%d] = %d\n", i, r[i]);
}
return r;
}
/* 要呼叫上面定義函式的主函式 */
int main ()
{
/* 一個指向整數的指標 */
int *p;
int i;
p = getRandom();
for ( i = 0; i < 10; i++ )
{
printf( "*(p + %d) : %d\n", i, *(p + i));
}
return 0;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526
指向陣列的指標
可以先了解了 C 指標的概念之后,再來學習本章的內容,
陣列名是一個指向陣列中第一個元素的常量指標,因此,在下面的宣告中:
double balance[50];
balance 是一個指向 &balance[0] 的指標,即陣列 balance 的第一個元素的地址,因此,下面的程式片段把 p 賦值為 balance 的第一個元素的地址:
double *p;
double balance[10];
p = balance;
使用陣列名作為常量指標是合法的,反之亦然,因此,*(balance + 4) 是一種訪問 balance[4] 資料的合法方式,
一旦您把第一個元素的地址存盤在 p 中,您就可以使用 p、(p+1)、*(p+2) 等來訪問陣列元素,下面的實體演示了上面討論到的這些概念:
#include <stdio.h>
int main ()
{
/* 帶有 5 個元素的整型陣列 */
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
int i;
p = balance;
/* 輸出陣列中每個元素的值 */
printf( "使用指標的陣列值\n");
for ( i = 0; i < 5; i++ )
{
printf("*(p + %d) : %f\n", i, *(p + i) );
}
printf( "使用 balance 作為地址的陣列值\n");
for ( i = 0; i < 5; i++ )
{
printf("*(balance + %d) : %f\n", i, *(balance + i) );
}
return 0;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
使用指標的陣列值
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
使用 balance 作為地址的陣列值
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000
在上面的實體中,p 是一個指向 double 型的指標,這意味著它可以存盤一個 double 型別的變數,一旦我們有了 p 中的地址,*p 將給出存盤在 p 中相應地址的值,
參考自:https://www.runoob.com/cprogramming/c-tutorial.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/208994.html
標籤:C
上一篇:在CentOS 7中使用BIND部署DNS服務器 - 主從DNS服務器
下一篇:資料結構入門-堆疊
