自已動手寫Redis【簡單動態字串序列一】

來源:互聯網
上載者:User

標籤:style   blog   http   io   使用   ar   strong   資料   2014   

第一章 簡單動態字串2.1 引言

字串String是程式設計中最為常見的一種資料結構,也是最為重要的一種資料結構,Hello World!這個最為精典的程式,是絕大部份人學習一種程式設計語言的入門程式,在這個最為精典的入門程式中,Hello World!就是字串類型,字串可以用於軟體中資訊的提醒、儲存等,Redis中key都是String類型的,因此瞭解String類型對於我們瞭解Redis以及動手寫Redis都是非常有益的。

2.2 字串基本概念

以上是我們最為熟悉的Hello World!程式,這兩段程式的輸出結果都是一樣的,資料結構上採用的也都是字串,但是兩者之間資料的儲存地區以及資料的訪問方式是完全不同的,程式2-1(a)與2-1(b)分別對應的字串為常量字串以及非常量字串,那麼兩者之間有什麼區別呢?

#include<stdio.h>

int main() {

char *hello = "hello world!";

printf("%s\n",hello);

return 0;

}

(a)

#include<stdio.h>

int main() {

char hello[] = "hello world!";

printf("%s\n",hello);

return 0;

}

(b)

代碼 2-1

2.2.1 常量/非常量

什麼是常量字串,由名字就可以看出,常量字串就是字串已經寫死了,不容許外界對其進行修改,那麼如何辯認字串是不是常量字串呢,常量字串與非常量字串一個重要區別就是在記憶體中儲存的位置是不一樣的,在程式中,將程式使用的空間大概劃分成以下幾個部份:

1、堆空間,在程式中堆空間一般由程式員進行分配與釋放,其生命週期由程式設計人員進行控制。

2、棧空間,由編譯器進行分配,用於存放程式中的局部變數、函數調用時的堆棧資訊等,棧空間的大小受限於作業系統的軟式節流以及記憶體的硬限制。
3、靜態儲存區,該地區儲存的是已初始化過的靜態變數(包括局部靜態變數以及全域靜態態量)、初化過的全域變數以及常量字串。

4、BSS內(未初始化的資料區),該地區主要用來存放全域未初始設定變數,BSS區的資料在程式開始運行之前會被核心初始化為0或者null 指標。

5、代碼區,存放待執行的機器指令,該地區通常是唯讀儲存區,避免由於對記憶體的誤操作,導致代碼啟動並執行不正常。

下面通過一段簡單的代碼來說明C程式執行時的記憶體配置情況【代碼2-2所示】,代碼部分已經寫了詳細的註解:

#include<stdio.h>

#include<stdlib.h>

int a;//未初始化的全域變數儲存在BSS區

static int t;//未初化的全域靜態變數,儲存在BSS區

int t = 0;//已初始化的全域變數,儲存在靜態儲存區

static int m = 0;//已初始化的全域靜態變數,儲存在靜態儲存區

int main() {

char c = ‘a‘;//函數局部變數,儲存在棧中

static int m; //未初化的局部靜態變數,儲存在BSS區

static int q = 0;//已初始化的局部靜態變數,儲存在靜態儲存區

char *addr = (char *) malloc(sizeof(char)*2);//在堆中分配2位元組

char *p = "Hello World!";//Hello World存放在靜態儲存區中

}

代碼 2-2

作業系統為了節省記憶體,將程式中的常量字串儲存在靜態儲存區,程式運行時可以共用這些常量字串,無需在開設空間用來儲存這些常量字串,我們將儲存在靜態儲存區中的字串稱為常量字串,將儲存在堆棧中的字串稱為非常量是字串,非常量字串也就意味著在程式啟動並執行過程中可以動態產生字串,也可以對已有的字串進行修改,下面的代碼2-3顯示了常量/非常量字串的一個重要區別。

#include<stdio.h>

int main() {

char *ptr = "Hello World!";

*(ptr+1) = ‘W‘;

printf("%s",ptr);

}

(a)

#include<stdio.h>

int main() {

char ptr[] = "Hello World!";

*(ptr+1) = ‘W‘;

printf("%s",ptr);

}

(b)

代碼 2-3

在上述代碼2-3(a)中,Hello World!是一個常量字串,儲存在靜態儲存區中,程式編譯是不會報錯的,但是程式運行時會出現執行階段錯誤,如2-4所示,這是因為在程式的執行過程中我們試圖通過指標修改靜態記憶體區中的常量字串,而靜態記憶體區中的常量字串是唯讀屬性,作業系統不允許外界對其進行修改,因此程式執行時會報執行階段錯誤。

圖2-4 執行階段錯誤

與代碼2-3(a)相比,代碼2-3(b)並沒有多大的改變,惟一的改變就是將指標ptr改成了數組,但是這種改變,對編譯器卻造成了不同的影響,在代碼2-3(a)中,編譯器發現*ptr是一個指標,會在棧中開設4位元組的變數用來儲存ptr這個指標的變數,同時發現ptr這個指標變數已經初始化了,指向Hello World!這個字串,編譯器會將Hello World!這個字串作為常量字串儲存在靜態儲存區中,並將其地址放在ptr這個指標變數中,代碼2-3(b)中,編譯器會發現ptr是一個數組,這時編譯器的行為就是用Hello World!這個字串來初始化ptr數組,ptr數組的長度編譯器在初始化的過程中會計算出來,即為Hello World!字串的長度13【備忘:C語言中的字串是以\0進行結尾的,因此實際長度要加上1】。

自已動手寫Redis【簡單動態字串序列一】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.