日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C字符串数组赋值

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C字符串数组赋值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C字符數組賦值

舉例如下:

char a[10];
1、定義的時候直接用字符串賦值
char a[10]="hello";
注意:不能先定義再給它賦值,如
?char a[10];
?a[10]="hello";
這樣是錯誤的!

2、對數組中字符逐個賦值
char a[10]={'h','e','l','l','o'};

3、利用strcpy
char a[10];
strcpy(a, "hello");

易錯情況:
1、char a[10]; a[10]="hello";//一個字符怎么能容納一個字符串?況且a[10]也是不存在的!
2、char a[10]; a="hello";//這種情況容易出現,a雖然是指針,但是它已經指向在堆棧中分配的10個字符空間,現在這個情況a又指向數據區中的hello常量,這里的指針a出現混亂,不允許!

還有:不能使用關系運算符“==”來比較兩個字符串,只能用strcmp() 函數來處理。


C語言的運算符根本無法操作字符串。在C語言中把字符串當作數組來處理,因此,對字符串的限制方式和對數組的一樣,特別是,它們都不能用C語言的運算符進行復制和比較操作。直接嘗試對字符串進行復制或比較操作會失敗。例如,假定str1和str2有如下聲明:

char str1[10], str2[10];

利用=運算符來把字符串復制到字符數組中是不可能的:

str1 = "abc";???? /*** WRONG ***/

str2 = str1;?????? /*** WRONG ***/

C語言把這些語句解釋為一個指針與另一個指針之間的(非法的)賦值運算。但是,使用=初始化字符數組是合法的:

char str1[10] = "abc";

是因為在聲明中,=不是賦值運算符。

試圖使用關系運算符或判等運算符來比較字符串是合法的,但不會產生預期的結果:

if (str1==str2) ...??? /*** WRONG ***/

這條語句把str1和str2作為指針來進行比較,而不是比較兩個數組的內容。因為str1和str2有不同的地址,所以表達式str1 == str2的值一定為0。

strcpy和memcpy的區別

strcpy和memcpy都是標準C庫函數,它們有下面的特點。
strcpy提供了字符串的復制。即strcpy只用于字符串復制,并且它不僅復制字符串內容之外,還會復制字符串的結束符

已知strcpy函數的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般內存的復制。即memcpy對于需要復制的內容沒有限制,因此用途更廣
void *memcpy( void *dest, const void *src, size_tcount);

?
char * strcpy(char* dest,constchar* src) // 實現src到dest的復制 {   if((src == NULL) || (dest == NULL))//判斷參數src和dest的有效性   { ??       returnNULL;   }   char*strdest = dest;???????//保存目標字符串的首地址   while((*strDest++ = *strSrc++)!='\0');//把src字符串的內容復制到dest下   returnstrdest; } void*memcpy(void*memTo,constvoid*memFrom,size_tsize) {   if((memTo == NULL) || (memFrom == NULL))//memTo和memFrom必須有效 ?????????returnNULL;   char*tempFrom = (char*)memFrom;????????????//保存memFrom首地址   char*tempTo = (char*)memTo;?????????????????//保存memTo首地址??????   while(size -- > 0)???????????????//循環size次,復制memFrom的值到memTo中 ???????  *tempTo++ = *tempFrom++ ;??   returnmemTo; }

strcpy和memcpy主要有以下3方面的區別。
1、復制的內容不同strcpy只能復制字符串而memcpy可以復制任意內容,例如字符數組、整型、結構體、類等
2、復制的方法不同strcpy不需要指定長度,它遇到被復制字符的串結束符"\0"才結束,所以容易溢出memcpy則是根據其第3個參數決定復制的長度
3、用途不同通常在復制字符串時用strcpy,而需要復制其他類型數據時則一般用memcpy

?

memset
原型:extern void *memset(void *buffer, int c, int count);
用法:#include <string.h>
功能:把buffer所指內存區域的前count個字節設置成字符c。
說明:返回指向buffer的指針。用來對一段內存空間全部設置為某個字符。

舉例:char a[100];memset(a, '\0', sizeof(a));

memset可以方便的清空一個結構類型的變量或數組。

如:
struct sample_struct
{
char ? csName[16];
int ? iSeq;
int ? iType;
};

對于變量
struct sample_strcut stTest;

一般情況下,清空stTest的方法:
stTest.csName[0]='\0';
stTest.iSeq=0;
stTest.iType=0;

用memset就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));

如果是數組:
struct sample_struct ? TEST[10];

memset(TEST,0,sizeof(struct sample_struct)*10);

對這個問題有疑問,不是對函數的疑問,而是因為沒有弄懂mem和str的區別。
mem是一段內存,他的長度,必須你自己記住
str也是一段內存,不過它的長度,你不用記,隨時都可以計算出來
所以memcpy需要第三個參數,而strcpy不需要

?

(一)strcmp函數??

???????? 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’;

}

至于程序中出現的指針的指針只是在思考時做的討論,上面的那么其實也可以看做普通指針,這里不做過多說明。

總結

以上是生活随笔為你收集整理的C字符串数组赋值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。