1. 程式人生 > >C字元陣列的賦值

C字元陣列的賦值

         strcmp函式是比較兩個字串的大小,返回比較的結果。一般形式是:  

                 i=strcmp(字串,字串);

         其中,字串1、字串2均可為字串常量或變數;i   是用於存放比較結果的整型變數。比較結果是這樣規定的:  

①字串1小於字串2,strcmp函式返回一個負值;

②字串1等於字串2,strcmp函式返回零;

③字串1大於字串2,strcmp函式返回一個正值;那麼,字元中的大小是如何比較的呢?來看一個例子。

         實際上,字串的比較是比較字串中各對字元的ASCII碼。首先比較兩個串的第一個字元,若不相等,則停止比較並得出大於或小於的結果;如果相等就接著 比較第二個字元然後第三個字元等等。如果兩上字串前面的字元一直相等,像"disk"和"disks"   那樣,   前四個字元都一樣,   然後比較第 五個字元,   前一個字串"disk"只剩下結束符'/0',後一個字串"disks"剩下's','/0'的ASCII碼小於's'的ASCII 碼,所以得出了結果。因此無論兩個字串是什麼樣,strcmp函式最多比較到其中一個字串遇到結束符'/0'為止,就能得出結果。

注意:字串是陣列型別而非簡單型別,不能用關係運算進行大小比較。  

         if("ABC">"DEF")   /*錯誤的字串比較*/

         if(strcmp("ABC","DEF")   /*正確的字串比較*/

(二)strcpy函式  

         strcpy函式用於實現兩個字串的拷貝。一般形式是:  

                 strcpy(字元中1,字串2)

         其中,字串1必須是字串變數,而不能是字串常量。strcpy函式把字串2的內容完全複製到字串1中,而不管字串1中原先存放的是什麼。複製後,字串2保持不變。  

例:    

         注意,由於字串是陣列型別,所以兩個字串複製不通過賦值運算進行。  

         t=s;   /*錯誤的字串複製*/

         strcpy(t,s);   /*正確的字串複製*/

昨天在用結構體指標給結構體賦初值的時候,犯了一個錯誤(main函式中被註釋掉的那一句話)。而應該採用strcpy的方式把一個字串放入字元陣列中去,對此我將沿著我探討這個問題根源的思路做一個分享

#include <stdio.h>

#include <string.h>

#include <malloc.h>

typedef struct student_info

{

       int number;

       char name[32];

}stu, *p_student;

int main()

{

       stu a;                                   //注意要定義一個結構體出來

       p_student p = NULL;

       p = &a;

       p->number = 1;

       //p->name = “aa”;  //錯誤

       strcpy(p->name, “aa”); //正確

       printf("%d:%s\n", p->number, a.name);

       return 0;

}

在發現這個問題之後,我進行了如下的幾個嘗試:指標對這個陣列成員不能賦值,那直接用結構體變數是否可以?(不行);採用普通方式,對結構體變數a在定義的時候初始化,是否可行?(可行)

那麼最終問題在於陣列初始化和賦值的方面,對此進一步採用了幾個程式,對該知識點進行了深入的理解,程式如下

#include <stdio.h>

#include <string.h>

int main()

{

       char a[] = "abcdef";

       char *p = "abcdef";

       char *p_a = NULL;

       //p_a = a;

       //fun(&p_a);

       //a[0] = 'z';

       //a = "z";

       //a = 'z';

       strcpy(a, "zf");

       //p = "z";

       *p = 'z';

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

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

       //printf("%s\n", p_a);

       return 0;

}

int  fun(char **ar)

{

       //char **p_a = &ar;

       *ar = "zef";

       //ar[0] = 'z';

//     strcpy(ar, "z");

       return 1;

}

以上是我在做知識點歸納時用的源程式,比較混亂,敬請了解。一下我將解釋一下,我到底做了那幾個方面的工作和討論

由於關係到字元陣列的賦值問題,我想到了這個例子,實驗了一下區別

把兩個相同的字串分別賦給一個字元陣列,和字元型指標。結果:均可以打印出來

那麼它們能否再被賦值修改呢?

於字元陣列而已只能通過a[0] = 'z';或者strcpy(a, "zf");這樣的方式對其進行修改,總結的時候再歸納原因

對於字元型指標p = "z";可以但是注意這裡的實質卻並沒有對p字串進行修改而*p = 'z';是不可行的

歸納總結一:

       參考網路知識和《c和指標》中關於字元陣列的初始化部分

(注意:需要提前搞清楚,什麼是賦值,什麼是初始化,什麼是定義。相關知識可以參考網路資料,eg:int a;(定義),int a = 10;(初始化),a = 10;(賦值))

1對於字元陣列:

       char a[15] = “abcdef”;

但不能做如下操作

       char a[15];

       a[15] = “abcdef”;

特別注意:第一種初始化的方式,看似左值是個字串,其實不然,它其實是個初始化列表。最後列表包含\0

因此,字元陣列是不能將字串賦給它的

       所以在後續的賦值裡必須對陣列元素進行賦值

2對於字串

       char *p = “abcdef”;

注意這裡不是把一個字串賦給了一個字元型的指標,而是把一個字元型的指標指向了字串的首地址

       所以上面p = "z"只是把指標指向了另一個地方而已

3對於陣列與字串在機器中的儲存

       陣列

                     陣列在機器中,當被定義時eg:char a[10];就已經分配好了記憶體空間,放在了資料段中,其中的數值是可以進行修改的

       字串

                     字串在記憶體中也被存放在了資料段中,但是字串又稱為字串常量,是編譯器“釘死”無法修改的,所以*p = 'z';想改變字串的值是不被允許的

之後我又進行了一些嘗試,那就是將陣列作為一個函式的引數進行傳遞,看變換,這個知識點,我不做操作上的過多複述。

歸納總結二:

       在此之前,我們首先得理解,陣列名。陣列名錶示著這個陣列的入口地址,這一點與函式名,結構體標識等類似。

       eg:char a[10];那麼a表示的是這個陣列第一個元素的地址即&a[0];

       而&a;表示的是這個陣列的首地址

       估計不少人這個時候糊塗了,這兩個有區別嗎?數值不一樣麼?

它們兩個的數值是一樣的,因為地址只有一個,陣列的一個元素的地址的值就是這個陣列的地址的值,那麼為什麼還要分這麼細緻呢?下面舉個例子

eg:

       char a[10];

       char *p = NULL;

       char (*p_a)[10] = NULL;

       p = a;

       p_a = &a;

如上面這個例子,a只能賦給一個char型的指標而&a只能賦給一個指向一個數組的指標(注意這裡的這個陣列要與你定義的那個a陣列同大小)

藉助指標,我們不難理解,其實他們所代表的一個指標的型別是截然不同的(如果不能理解請參考c相關教程中指標的概念)

進入正文,所以當一個數組被傳遞如函式的時候可以把陣列名傳進去也就是把這個陣列的第一個元素的首地址傳進去

作為指標被傳進去的陣列名這時和指標是完全一致的,可以作為指標使用,當然為直觀化,可以用做陣列

eg:

       char a[10];

       int fun(char *a)

       {

                     a[0] = ‘A’;

}