數(shù)組(C語言)

一剪廉、數(shù)組的定義

1、定義

數(shù)組:指針的特殊化朴肺。
它也是內(nèi)存分配(空間申請)的一種形式窖剑,而不是一種全新的數(shù)據(jù)結(jié)構(gòu)。

其目的就是為了定義一個連續(xù)的空間戈稿。

2西土、2個屬性:

  • 大小

  • 讀取方式

    數(shù)據(jù)類型 數(shù)組名[m]:
    
    []:把數(shù)組名升級為一個連續(xù)空間
    m:連續(xù)空間的個數(shù)。
    數(shù)據(jù)類型:表示內(nèi)存以何方式切割鞍盗。
    
    int a[100];   // 100個int這么大的連續(xù)空間
    
    a[10]   // 使用方式與指針是一樣的
    

(1)m 就是一個建議符需了,只是在申請的時候用一下。后面使用的時候般甲,編譯器無法知道[]里面的數(shù)是否越界肋乍。

int a[100];   // 理論上,a的空間只有100個敷存,但是只是建議墓造;還是可以越界的。

(2)經(jīng)典錯誤1:數(shù)組名是一個常量符號锚烦,只是一個標(biāo)簽常量觅闽,是無法改變的,一定不要放到=的左邊

char buf[100];
buf = "hello world";    // 錯誤涮俄!
buf++;    // 錯誤蛉拙!

數(shù)組名是一個常量,指針是一個變量禽拔。


二刘离、數(shù)組空間的初始化(數(shù)組空間的賦值問題)

原理:按照標(biāo)簽逐一賦值。(空間的賦值沒有投機(jī)取巧的辦法睹栖,只能這樣做)

int a[10];
a[0] = x;
a[1] = y;
...

問題:
但如果這樣賦值硫惕,程序員的工作量很大。
偷懶辦法:讓編譯器進(jìn)行一些自動處理野来,幫助程序員寫如上的逐一賦值的程序恼除。

方法:空間在定義時,就告知編譯器初始化情況,這叫空間的第一次賦值豁辉。

int a[10] = 空間;

C語言本身/CPU內(nèi)部本身令野,一般不支持空間和空間的拷貝,只支持int徽级、int(4B)等之間小的拷貝气破。

int a[10] = {10, 20, 30};   -- > 學(xué)習(xí)arm匯編后,可以進(jìn)行反匯編餐抢。
其內(nèi)部相當(dāng)于執(zhí)行一個拷貝的過程现使。只是不同編譯器調(diào)用不同的函數(shù)來做拷貝。

這句定義旷痕,其實CPU還是做了:
a[0] = 10;
a[1] = 20;
a[2] = 30;
a[3] = 0 / 隨機(jī)值;  (不同編譯器可能有所不同)
...
所以碳锈,一定不要這樣認(rèn)為:數(shù)組初始化一步就可以完成了!

數(shù)組空間的初始化和變量的初始化欺抗,本質(zhì)上是不同的售碳。
尤其在嵌入式的裸機(jī)開發(fā)中,數(shù)組空間的初始化往往需要一些庫函數(shù)的輔助绞呈,或者程序員的人為設(shè)計贸人。

1、字符空間(軟件的最小空間:char)

char buf[10] = {'a','b','c'};
// 1. buf如果當(dāng)成普通內(nèi)存來看,這樣寫沒有問題
// 2. buf如果當(dāng)成一個字符串來看,最后一定加上一個'\0'
字符串的重要屬性:結(jié)尾一定有個'\0'

(1)buf當(dāng)成字符串的寫法:

char buf[10] = {'a','b','c', '\0'};

char buf[10] = {"abc"};    
// buf當(dāng)成字符串最合理的寫法
// C語言編譯器看到雙引號,就會自動在末尾加上'\0'

char buf[10] = "abc";

char buf[] = "abc";

(2)經(jīng)典錯誤2

char buf[10] = "abc";
// buf有空間瞻离,再把abc逐一地拷貝到buf中
// 通過初始化方法完成了常量區(qū)向變量區(qū)的拷貝。
// 因此力惯,對buf變量區(qū)的值進(jìn)行修改是可以的;但無法對“abc”常量區(qū)進(jìn)行改動召嘶。
buf[2] = 'e';   //對變量區(qū)進(jìn)行修改父晶,沒有問題
char *p = "abc";
// p直接指向abc的地址
p[2] = 'e';    // 錯誤!不能對常量區(qū)進(jìn)行修改

(3)經(jīng)典錯誤1:數(shù)組名是一個常量符號弄跌,只是一個標(biāo)簽常量甲喝,是無法改變的,一定不要放到=的左邊铛只。

char buf[100] = "abc";    // 數(shù)組空間的初始化埠胖,是空間的第一次賦值,可以直接這樣寫
buf = "hello world";    // 錯誤淳玩!
// 想把空間的值變?yōu)槠渌背罚@是進(jìn)行空間的第二次賦值,就不能直接這樣寫了蜕着,只能逐一處理:
buf[0] = 'h';   
buf[1] = 'e'; 
... 
buf[n] = 'd';
buf[n+1] = 0;

C語言編譯器只支持第一次空間賦值(初始化)時谋竖,直接=來一次賦值红柱;第二次開始,必須進(jìn)行逐一賦值蓖乘。

問題:
第二次賦值锤悄,是很多人都有的需求,而逐一賦值工作量太大啦嘉抒!

鑒于此零聚,C語言提供了一套字符拷貝函數(shù)

2些侍、字符拷貝函數(shù)(strcpy握牧、strncpy)

字符拷貝函數(shù):內(nèi)存空間和內(nèi)存空間的逐一賦值功能的一個封裝體。

注意:一旦空間中出現(xiàn)了0這個特殊值娩梨,字符拷貝函數(shù)就將結(jié)束。
也就是說览徒,只有遇到\0狈定,strcpy和strncpy才會結(jié)束拷貝;否則會一直拷貝习蓬。

(1)strcpy

char *strcpy(char *dest, const char *src);

使用strcpy實現(xiàn)第二次空間賦值:

char buf[10] = "abc";
// buf = "hello world";
strcpy(buf, "hello world");   // 使用strcpy實現(xiàn)了第二次空間賦值纽什!

該函數(shù)存在嚴(yán)重的內(nèi)存泄漏問題,在工程中絕對不能使用躲叼!

char buf[10] = "abc";
strcpy(buf, "hello world, i am lixingzhi. How are you ? ...");
// buf只有10個連續(xù)空間芦缰,但是strcpy時字符串的字符多于10個,導(dǎo)致內(nèi)存泄漏

(2)strncpy

char *strncpy(char *dest, const char *src, size_t n);

3枫慷、非字符空間

字符空間:可以使用ASCII碼來解碼的空間让蕾,其目的是讓人看的(%s看字符空間的內(nèi)容,人可以看懂)

字符空間有字符串和結(jié)束標(biāo)志(\0)或听。

非字符空間

數(shù)據(jù)采集探孝,是8bit或其倍數(shù)為單位來進(jìn)行采集的。
所以需要開辟一個存儲這些數(shù)據(jù)的空間誉裆。

char buf[10];     // 看到char顿颅,第一反映就是:一定是個string(字符串) 
unsigned char buf[10];    // 看到unsigned char,一定是個data(普通數(shù)據(jù)足丢,非字符串) 

注意:非字符空間的第二次賦值粱腻,不能用strcpy和strncpy:

unsigned char *p = sensor_base;   // sensor的數(shù)據(jù)
strcpy(buf, p);
// strcpy遇到\0才會結(jié)束。sensor_base里很可能沒有\(zhòng)0斩跌,或者剛開始就是低電平(0)

問題:
字符空間的拷貝绍些,結(jié)束標(biāo)志為\0;那么非字符空間拷貝的結(jié)束標(biāo)志是什么耀鸦?

非字符空間沒有結(jié)束標(biāo)志遇革,只能定義拷貝的個數(shù)。
因此其拷貝的三要素:

  • src
  • dest
  • 拷貝的個數(shù)

4、memcpy

// man memcpy:
#include <string.h>

void *memcpy(void *dest, const void *src, size_t n);
// void *:非字符空間標(biāo)識符
// n:非字符空間的大小

例1:

int buf[10];
int sensor_buf[100];
// memcpy(buf, sensor_buf, 10);  錯誤B芸臁锻霎!  10是10個字節(jié)(char)
memcpy(buf, sensor_buf, 10 * sizeof(int));  // 拷貝的是10個int大小

例2:

unsigned char buf[10];
unsigned char sensor_buf[100];
memcpy(buf, sensor_buf, 10 * sizeof(unsigned char));

三、用指針表示數(shù)組

1揪漩、一維數(shù)組與一級指針

int b[100];    
int *p1 = b;    // 數(shù)組名就是數(shù)組首地址旋恼,可以賦給一個指針

2、指針數(shù)組與多級指針(二級指針)

int b[100];    // 100個空間都存的是int整型值

// 指針數(shù)組
char *a[100];    // 100個空間都存的是*(指針)奄容,指針對取的方式是char(一個字節(jié)一個字節(jié)地操作)
sizeof(a) = 100 * 4;    // 1個地址4個字節(jié)

// 二級指針
char **a ;

// 指針數(shù)組和二級指針冰更,都通過a[0]、a[1]這樣的方式訪問
char *a[100]首地址被指針指向昂勒,就成了char **a

3蜀细、多維數(shù)組(二維數(shù)組)

(1)Q:二維數(shù)組與二級指針有關(guān)嗎?

// 定義一個指針戈盈,指向int b[5][6]的首地址

// 錯誤5煜巍:
int **p2 = b;

例1:

// 001.c
#include <stdio.h>
int main()
{
    int a[5][6];    // 二維數(shù)組

    int **p2 = a;    // 二級指針
    return 0;
}
無效的指針類型:p2讀內(nèi)存的方式,和a讀內(nèi)存的方式是不一樣的
二維數(shù)組與二級指針沒有一點關(guān)系塘娶,完全不一樣

二維數(shù)組與二級指針沒有一點關(guān)系归斤,完全不一樣。
二級指針:只是描述地址的線性關(guān)系刁岸,是地址的一個存儲器脏里。
二維數(shù)組:一塊一塊地讀內(nèi)存。

(2)Q:二維數(shù)組該如何用指針表示虹曙?

int a;    // 一個int型變量a
int *p;    // 一個int型指針p

int a[5];    
int *p[5];    
int (*p)[5]; 

例2:

// 002.c
#include <stdio.h>
int main()
{
    int a[5][6];
    int (*p2)[6] = a;    // 指針表示二維數(shù)組
    return 0;
}
這次編譯沒有警告了迫横,說明a[5][6]讀內(nèi)存的方式,和(*p2)[6]讀內(nèi)存的方式是一樣的

(3)多維數(shù)組

int b[2][3][4];    // 多維數(shù)組
int (*p)[3][4] = b;    // 指針表示多維數(shù)組
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酝碳,一起剝皮案震驚了整個濱河市员淫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌击敌,老刑警劉巖介返,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沃斤,居然都是意外死亡圣蝎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門衡瓶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來徘公,“玉大人,你說我怎么就攤上這事哮针」孛妫” “怎么了坦袍?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長等太。 經(jīng)常有香客問我捂齐,道長,這世上最難降的妖魔是什么缩抡? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任奠宜,我火速辦了婚禮,結(jié)果婚禮上瞻想,老公的妹妹穿的比我還像新娘压真。我一直安慰自己,他們只是感情好蘑险,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布滴肿。 她就那樣靜靜地躺著,像睡著了一般佃迄。 火紅的嫁衣襯著肌膚如雪泼差。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天和屎,我揣著相機(jī)與錄音,去河邊找鬼春瞬。 笑死柴信,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宽气。 我是一名探鬼主播随常,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼萄涯!你這毒婦竟也來了绪氛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涝影,失蹤者是張志新(化名)和其女友劉穎枣察,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體燃逻,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡序目,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伯襟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猿涨。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姆怪,靈堂內(nèi)的尸體忽然破棺而出叛赚,到底是詐尸還是另有隱情澡绩,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布俺附,位于F島的核電站肥卡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昙读。R本人自食惡果不足惜召调,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛮浑。 院中可真熱鬧唠叛,春花似錦、人聲如沸沮稚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕴掏。三九已至障般,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盛杰,已是汗流浹背挽荡。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留即供,地道東北人定拟。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像逗嫡,于是被迫代替她去往敵國和親青自。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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