1. 程式人生 > >c語言==字元陣列與字串,char的取值範圍(1)

c語言==字元陣列與字串,char的取值範圍(1)

求char型別陣列的strlen長度

昨天老師給了一道題目
#include <stdio.h>
#include "string.h"

int main()
{
    int i;

    char a[1000];

    for(i = 0; i < 1000; i++)
    {
    a[i] = - i - 1;
    }

    printf("strlen(a)=%d\n", strlen(a));

    return 0;
}

當時心想這個答案不就是1000嗎。我甚至想了1001,因為想到字串有\0。

但是後來才意識到了這是要求的是strlen。1000的這個陣列的sizeof。

sizeof求的是陣列的空間容量,而strlen求的是陣列的實際長度,有多少數字字元儲存在裡面。

上面說到\0 因為我現在大二 大一的時候沒有好好學c語言,怎麼都入不了門 現在再回顧的時候發現一些細節還是處理不好。

首先談談\0與strlen的關係。
strlen一遇到\0他就不會再繼續下去了,所以他當然是不會去計算\0的個數的。
strlen("abcd\0ef\ng\0")
這個答案應該是4,因為他遇到第一個\0就自動停止了。只讀了abcd。

再說說\0與sizeof的關係
sizeof是表示陣列情況的,而字元陣列在初始化的時候是不加’\0’的。所以sizeof不包括’\0’,只是輸出初始化資料的數量


這裡寫圖片描述
剛才為了這條題目花了好長時間。感覺要是自己平時不寫部落格。這些東西隨隨便便就放掉了。但是寫部落格的話感覺都要理清楚,似乎要寫到宇宙起源2333。
首先我看到這個題目的時候我還是有點蒙圈的。因為不自信。看起來一樣但是總感覺不是那麼簡單的。然後我就敲程式碼測試了一下。
發現什麼呢,
a字串不管加不加static,他的strlen是6,sizeof是7.
如果中括號硬要寫數字,那麼裡面要寫上7才能正確的儲存賦進去的值。
b陣列如果單單像圖片上那樣,sizeof=6,strlen是肯定得不到的,陣列字元也不對。
有兩種解決辦法
1、加上static 所有的都bingo。sizeof=資料的數量
2、在數組裡面加上’\0’,sizeof=資料的數量+1,字串和strlen bingo.

百度了一下static,是為了相容編譯器還有分配靜態儲存空間什麼的。但是還是不知道為什麼加了他就能正確輸出了,求大牛指點。

後來翻了一下課本,發現了一些不得了的東西。字元陣列和字串。
樣子差不多,其實就差了個’\0’。有就是字串,沒有就是字元陣列。

所以可以得出結論:
平常所說的a[n]

如果他作為一個字元陣列
//字元陣列都是外面大括號,裡面的字元用單引號括起來
如char b[]={‘a’,’b’,’c’},這個時候你寫了三個值進去了,

如果你中括號裡不寫任何東西,此時你求sizeof,它是=3的,strlen無法確定,你寫進去的值也沒辦法好好輸出。
如果你中括號寫了3,它的sizeof毫無疑問是3,strlen無法確定,值也沒辦法輸出
如果你中括號寫了4,一切都是對的

所以如果他是作為字元陣列的a[n],那麼他的sizeof是n,strlen是……鬼知道呢,是你自己輸入資料的長度,幾個數 strlen就是幾。如果中括號沒n,則sizeof=資料的數量

但是他如果是作為字串
//字串兩種表達方式,要麼是雙引號直接括起來,要麼是外面大括號裡面雙引號。
如char a[]=”abc”,這個字串有三個數

如果你中括號裡不寫任何數,那麼他輸出的sizeof是3+1,strlen是3,字串也能好好輸出。
如果你中括號寫3 sizeof是3,strlen很混亂,字串也不太好。哈哈意思就是他們都是錯的。
如果中括號寫4 輸出的都是對的,sizeof=4,strlen=3,字串也好好的。

所以字串很乖,a[n]表示他有n-1個數字,strlen=n-1,sizeof=n,字串是n-1個輸出。如果沒n,sizeof=資料的數量+1,strlen=資料的數量

Sizeof與Strlen的區別與聯絡(轉)

1.sizeof操作符的結果型別是size_t,它在標頭檔案中typedef為unsigned int型別。
該型別保證能容納實現所建立的最大物件的位元組大小。

2.sizeof是算符,strlen是函式。

3.sizeof可以用型別做引數,strlen只能用char*做引數,且必須是以”\0”結尾的。
sizeof還可以用函式做引數,比如:
short f();
printf(“%d\n”, sizeof(f()));
輸出的結果是sizeof(short),即2。

4.陣列做sizeof的引數不退化,傳遞給strlen就退化為指標了。

5.大部分編譯程式 在編譯的時候就把sizeof計算過了 是型別或是變數的長度這就是sizeof(x)可以用來定義陣列維數的原因
char str[20]=”0123456789”;
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;

6.strlen的結果要在執行的時候才能計算出來,時用來計算字串的長度,不是型別佔記憶體的大小。

7.sizeof後如果是型別必須加括弧,如果是變數名可以不加括弧。這是因為sizeof是個操作符不是個函式。

8.當適用了於一個結構型別時或變數, sizeof 返回實際的大小,
當適用一靜態地空間陣列, sizeof 歸還全部陣列的尺寸。
sizeof 操作符不能返回動態地被分派了的陣列或外部的陣列的尺寸

9.陣列作為引數傳給函式時傳的是指標而不是陣列,傳遞的是陣列的首地址,
如:
fun(char [8])
fun(char [])
都等價於 fun(char *)
在C++裡引數傳遞陣列永遠都是傳遞指向陣列首元素的指標,編譯器不知道陣列的大小
如果想在函式內知道陣列的大小, 需要這樣做:
進入函式後用memcpy拷貝出來,長度由另一個形參傳進去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}

我們能常在用到 sizeof 和 strlen 的時候,通常是計算字串陣列的長度
看了上面的詳細解釋,發現兩者的使用還是有區別的,從這個例子可以看得很清楚:

char str[20]=”0123456789”;
int a=strlen(str); //a=10; >>>> strlen 計算字串的長度,以結束符 0x00 為字串結束。
int b=sizeof(str); //而b=20; >>>> sizeof 計算的則是分配的陣列 str[20] 所佔的記憶體空間的大小,不受裡面儲存的內容改變。

上面是對靜態陣列處理的結果,如果是對指標,結果就不一樣了

char* ss = “0123456789”;
sizeof(ss) 結果 4 ===》ss是指向字串常量的字元指標,sizeof 獲得的是一個指標的之所佔的空間,應該是

長整型的,所以是4
sizeof(*ss) 結果 1 ===》*ss是第一個字元 其實就是獲得了字串的第一位’0’ 所佔的記憶體空間,是char類

型的,佔了 1 位

strlen(ss)= 10 >>>> 如果要獲得這個字串的長度,則一定要使用 strlen

啊。繞了這麼久,圖片上的題目答案還沒得出來。
首先感覺題目有點問題,a不是陣列時字串呀。要求長度就是字串的長度就是strlen,那麼就是6。b是一個字元陣列。沒有寫上’\0’。求它的長度,那麼就是sizeof了。也是6。我感覺應該是相等的,但是僅僅是個人意見。這個題目是百度別的東西的時候看到的,題主並沒有給答案,求大牛指導。

啊,我以後肯定不能當老師,不然光扯了。可能上課拋的第一個問題都沒回答呢。

接下來回答一下第一個困擾我的問題。

#include <stdio.h>
#include "string.h"

int main()
{
    int i;

    char a[1000];

    for(i = 0; i < 1000; i++)
    {
    a[i] = - i - 1;
    }

    printf("strlen(a)=%d\n", strlen(a));

    return 0;
}

為了方便,我就粘下來了。首先strlen的型別要是char型別的。char型別無符號數的範圍是0-255,有符號型是-128~127
這道題目-i-1=127的話,i=-128,如果是-129,那麼將超出127.
假如-i-1=-128的話,i=127,如果是128,那麼將超出-128.
然後我的理解就是127+128.
意思就是誰的值是0,那麼他的下標就是範圍了。和這道題目類似的一道題目
裡面有詳盡的解釋。

字元陣列

形式是char a[] = {‘A’,’B’,’C’}

字串

形式是char a[] = “abcd”或者是char a[] = {“abcd”}

字串的初始化必須要加\0
char a[] = {‘a’,’b’,’c’,’\0’}