數據結構作業復盤1:字符串疑難雜癥小匯總(字符串賦值,指針數組...)

學校里開始上數據結構了,一開始是從C語言一些相關的基礎開始講起。第一次作業主要是字符串相關的基礎知識以及編程題目。先做了一部分,整理了一下一些字符串隱含的知識和一些易誤易混的概念,算是給自己的一個復盤和歸納。

strcpy函數相關

首先來看一下這段代碼

char s[7]="abcdef",a[4]="ABC";

strcpy(s,a);

printf("%s,s);

?一開始的時候我以為會輸出ABCdef,但是只輸出了ABC。相信應該也會有人和我一樣犯這種錯誤,本質上還是對strcpy本質不了解。本質上其實是把a的首地址復制到了s上,所以打印的時候自然不會把s的內容也給輸出出來。

那我們不妨把a的長度變為9,變成ASDFGHJK(注意還有個\0),再進行復制后,輸出的s竟然還是ASDFGHJK,這就說明了一個問題:復制地址的時候,目標字符串(前者s)的長度和原字符串(后者a)的長度并不會影響復制,即使前者的長度比后者短,依舊可完整的輸出原字符串(a)。這體現了地址傳遞與值傳遞的差異所在。

同時,通過閱讀《C Primer Plus》,我還了解到了strcpy函數另外的幾個特點:

1.strcpy的返回值是char*類型,具體來說是其中第一個參數的地址,比如:strcpy(s+2,a);返回的就是s+2這個指針。

2.第一個參數不用指向目標字符串的首地址,就像上面的例子,可以使s+2,這樣我們可以進行在數組的中部進行插入,值得注意的是,在中部插入之后,原來字符串的后半部分也是不會再有的了,全部都是新復制進來的字符串

3.strcpy函數如果要進行復制的話,其目標字符串指針必須指明地址,否則將指向一個不定的位置造成錯誤。

4.聲明一個數組(char s[2])會自動為你分配內存,但是僅聲明一個指針(char*s)不會給存儲數據用的空間,僅僅會給一個存儲地址的空間。

5.假如你是給字符串數組復制了一個常量字符串,那么后面你就不能在對他進行修改了。比如以下代碼就會報錯:

char sr[5];
strcpy(sr,"qwer");
sr="qq";

關于字符串,字符數組的賦值問題

來看下面的代碼

char a[3];
char b[]="china";
a=b;
printf("%s",a);

乍一看上去好像沒有什么問題 ,但是編譯會報錯。

?

所以我們來總結一下有關字符串,字符指針的賦值問題。

參考文章:c語言中不能將字符串賦值給字符數組,c - "error:對具有數組類型的表達式的賦值 error"

1.這個問題翻譯過來是對具有數組類型的表達式的賦值?,也就是說,作為一個左值,數組類型是不可以被進行賦值的,這個是c11的規定,就按照規定來就好了。

2.char a[10]="hello";這個語句是正確的,從中我的理解是:如果初始化和數組聲明在同時進行,是不會出問題的,此時雖然左邊是數組類型,但是右邊的字符串不再是常量,而是被理解為變量;但是如果先聲明數組再進行初始化就會有問題,這時我們進行的是賦值操作,此時右邊的字符串就是一個常量了

3.如果聲明的是char s[12],在后面的時候就會把s理解為數組類型;如果聲明的是char*s,那后面就會把s理解為指針,數組是不能被進行賦值的,而對于指針而言,如果它作為左值,無論右邊是數組的首地址還是純粹的指針,都是正確的。下面的代碼都是正確的。

?

?

?賦值時的長度問題

來看下面的代碼:

char a[3];strcpy(a,"qwerty");
char b[3]="china";

如果將他們兩個進行輸出,會產生什么結果呢?

?

?所以根據這個我們來總結一下不同方法賦值的長度問題:

1.如果使用strcpy函數,那么,無論前面的長度是多少,都是可以的,因為本質上復制的是字符串的地址,與存儲空間無關。

2.如果直接將字符串賦值給字符數組,那么假如字符數組沒有足夠長的空間,就會把字符串進行截斷,只保留它的空間所能容納的長度。

字符串結尾‘\0’問題的研究

這篇文章的大佬講的很細致了,鏈接在這:字符串結束符'\0' -何時自動加- 字符串定義方法

我在這里還是自己再總結一遍加深印象:

如果使用字符數組進行對字符串的定義:

1.char s[5]={"ABCDE"};這種方法不會給字符串末尾加上‘\0’。如果字符串長度等于數組所聲明的長度,他是不會加上‘\0’的。

2.char s[10]={"ABCDE"};字符串長度小于數組所聲明的長度,會把還未初始化的元素自動變成‘\0’,也就是說后面五個元素全部都是'\0'。

3.char s[]="ABCDE";一開始沒有聲明數組長度,進行賦值以后,會在后面加上'\0'。對比1,我試了一下,打印sizeof(s)的話,第一種是5,而第三種是6,這說明第三種方法后面有‘\0’而第一種沒有。

4.char s[]={'A','B','C',‘D’,‘E’};這種方法相當于一個字符一個字符的賦值,所以也不會加上‘\0’.

5.char s[10]={'A','B','C',‘D’,‘E’};和前面的3類似,后面五個會被初始化為‘\0’。

如果使用字符指針對字符串進行定義

使用指針的話,就沒什么大問題了,后面一定是會加上‘\0’的,前面說過,字符指針作為左值是既可以初始化(char* s=“qwert”),又可以直接用自己賦值的(char*s;s=“qwert”)而字符數組只能夠進行前者(char s[10]="qwert"),不能夠進行后者(char s[10]; s="qwert"),如果想要賦值,必須使用strcpy函數。

轉義字符的小問題

來看代碼

char s[]="\t\v\\\0wwww";

printf("%d",strlen(c));

?輸出的長度是3,我們知道\0是字符串的終止符,所以前面是字符串的內容,關于長度是三這個問題,總結一下:

1.\? 作為C語言中的轉義字符,是用來表達在ASCII碼表中不可見字符和控制符的。類似于\t,\v,\n,他們是控制符,如果你在ASCII表里去尋找這些字符,他們是不會以\t,\v,\n的形式出現的。因此如果想要輸出他們,就需要使用轉義字符和別的字母一起來實現控制符的意思。這些控制符是作為一個整體存在的,也就是說\t,\v是只占一個字符的位置的。

2.\還有的功能是轉換那些單獨打印無法打印的字符的,比如\,",如果你想單獨在printf的引號中去打印這些字符,是無法輸出的,這就需要轉義字符了。比如\\,實際上最后只輸出一個\。

綜上,上面的字符串相當于是有\t,\v,\三個字符,注意,strlen是不會讀取‘\0’的,而sizeof才會輸出包含‘\0’的長度。

指針數組與數組指針

char* s[]={"abc","ABC","QWE","qqqqq"};

上面的這個數組與之前的有所區別,我們可以看到,s前面的類型是char*,也就是說,存放在這個數組里的是指向char的指針,也就是里面字符串的首地址。我們可以把這個理解為一個二維的字符串數組。

下面來介紹幾個輸出的內容:

1.*(s+2)或者s[2],是字符串的首地址,用%s來輸出,代表的是QWE這整個字符串。?

2.*((*(s+2))+2)或者s[2][2]輸出的是E這個字符。

3.*s[2]或者**(s+2),用%c輸出,代表的是Q這個字符,也就是說,把首地址所指向的字符給打印了出來。(這個點容易混淆)

歸根到底,s+i代表的是指向字符串的指針的指針(有點拗口),是一個二級指針s[i]代表的是指向字符串的指針,是一個一級指針。從此延伸,加上*就是一層一層的取內容了。比如如果想用s+i來取出字符串本身,那就要兩個*,第一個*代表的是字符串的首地址,第二個*才是字符串本身。

char(*s)[10];

這里的s代表的是這樣的含義:首先s是一個指針,去掉*和變量名之后,剩下char[10],也就是說,s所指向的內容是一個長度為10的char型數組,指向的是數組!

我們可以把它叫做行指針,因為在二維的數組中,每一行都是一個一維數組,而這個指針正是指向一個一維的數組的。?

注意數組指針和數組的首地址的區別。數組指針本身雖然也是數組首地址,兩者僅僅是在數值上相等,兩者所指向的內容并不一樣。數組指針指向的是數組整體,而數組首地址如果不是字符數組,而是其他類型比如整型數組的時候,指向的僅僅是第一個元素。比如以下代碼:

char str[3][10]={"qwertyuiop","qwr","uiop"};
char(*s)[10];
s=str;
s+=2;
printf("%s",s);

最后輸出的時候,輸出的是uiop,也就是說,對于一個數組指針,它的加減是以所指向的數組長度決定的,每加一次,他都會跳過整個數組的長度,如果在二維數組中的話,就相當于他跳到了下一行?。

相比之下,普通的數組首地址如果加1的話,由于它所指向的是首元素,因此只會跳到下一個元素去,不會把整個數組越過。

也就是說,指針的加減是由指針所指向的數據類型決定的。加減都會以數據的字節數為單位。這從另外一個角度展示了數組指針和數組首地址的區別。

好了以上就是我自己整理過的關于字符串的很多疑難雜癥和邊邊角角,希望對大家有幫助。

整理不易,最后給個一鍵三連再走吧~~~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717076.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

System Verilog學習筆記(十五)——包的使用

System Verilog學習筆記(十五)——包的使用 為了使得可以在多個模塊或者類之間共享用戶定義類型,SV添加了包(package)。用戶自定義的類型例如類、方法、變量、結構體、枚舉類型等都可以在package…endpackage中定義。…

sc-MAVE

Deep-joint-learning analysis model of single cell transcriptome and open chromatin accessibility data單細胞轉錄組和開放染色質可及性數據的深度聯合學習分析模型 在同一個細胞中同時分析轉錄組和染色質可及性信息為了解細胞狀態提供了前所未有的解決方案。然而&#x…

數據結構——基本概念與術語2,抽象數據類型的表示與實現

目錄 1.數據類型 2.抽象數據類型 1.抽象數據類型的形式定義 基本操作定義格式說明 2.抽象數據類型定義舉例:circle的定義 3.抽象數據類型定義舉例:復數的定義 概念小結: 3.抽象數據類型的表示與實現 1.數據類型 2.抽象數據類型 比如一…

Stable Diffusion webui 常用啟動參數

automatic1111 (stable diffusion webui開源項目) --listen 開啟遠程訪問,局域網內主機可通過ip地址訪問SD webui主機 --share 開啟互聯網訪問,任何主機都可訪問主機,啟動后會在啟動文本上顯示訪問鏈接 --port 通常…

游戲框架搭建

使用框架的目標:低耦合,高內聚,表現和數據分離 耦合:對象,類的雙向引用,循環引用 內聚:相同類型的代碼放在一起 表現和數據分離:需要共享的數據放在Model里 對象之間的交互一般有三…

跨平臺指南:在 Windows 和 Linux 上安裝 OpenSSL 的完整流程

Windows安裝 一:找到安裝包,雙擊即可 https://gitee.com/wake-up-again/installation-package.git 二:按照提示,一步一步來,就可以啦 三:此界面意思是,是否想向創作者捐款,自己視情…

2024最新搭建Mybatis配置教程【超詳細】

為什么要學習mybatis 首先要弄清楚什么是mybatis?我們為什么要學mybatis 學習MyBatis可以幫助開發人員更高效地進行數據庫操作,提高開發效率,并且可以使得應用程序更具可維護性和性能優勢。 我們知道Java程序操作數據庫是通過jdbc與數據庫進…

藍橋杯——矩形拼接

矩形拼接 題目分析 對于一個矩形而言,我可以把它橫著放,而可以把它豎著放,比如下圖, 3個矩形的拼接情況可以通過在紙上畫圖模擬出來,情況有以下三種 ? 圖1 圖3是4條邊,即四邊形。觀察一下什么時候會是四…

IO(Linux)

文件系統 前言1. 回顧關于C文件部分函數2. 一些文件知識的共識3. 相對路徑4. fwrite中的\0 一、文件描述符fd1. 概念2. 系統調用① open 和 close② write③ read 和 lseek 3. 缺省打開的fd 二、重定向1. 原理2. 系統調用dup23. stdout和stderr的區別4. 進程替換和原來進程文件…

【計算機考研】408學到什么程度才能考130?

408考130要比考研數學考130難的多 我想大部分考過408的考生都是這么認為的。408的難點在于他涉及的范圍太廣了,首先如果你要備考408,你要準備四門課程,分別是數據結構,計算機組成原理,操作系統和計算機網絡。 這四門…

kafka學習筆記四(面試題)

[Kafka 常見面試題]如何保證消息的不重復不丟失-阿里云開發者社區 (aliyun.com) 18道kafka高頻面試題哪些你還不會?(含答案和思維導圖)-阿里云開發者社區 (aliyun.com) Leader Epoch機制解決的是數據丟失或不一致的問題,見下文&…

報錯解決:av.codec.codec.UnknownCodecError: libx264

1. 錯誤信息 今天在使用Pytorch.io和PyAV包的時候出現了這個錯誤,完整的錯誤信息如下所示: ...envs\tf2_py38\lib\site-packages\torchvision\io\video.py", line 92, in write_videostream container.add_stream(video_codec, ratefps)File &qu…

企業計算機服務器中了360勒索病毒如何解密,360后綴勒索病毒處理流程

對于眾多的企業來說,企業的數據是企業發展的核心,越來越多的企業開始注重企業的數據安全問題,但隨著網絡技術的不斷發展與應用,網絡黑客的攻擊加密手段也在不斷升級。近期,云天數據恢復中心接到多家企業的求助&#xf…

設計模式—命令模式:探索【命令模式】的奧秘與應用實踐!

命令模式 命令模式是一種行為設計模式,它的主要目的是將請求封裝成一個對象,從而使得請求的發送者和接收者之間進行解耦。 在命令模式中,命令被封裝為一個對象,包含了需要執行的操作以及執行這些操作所需的所有參數。 命令的發送者…

【藍橋杯】2023省賽真題詳解(更新中)

🐏小憐憐的簡介: 💖博客主頁:浣熊小憐憐 🚀年齡:23 大三在讀 💪愛好:干飯,運動,碼代碼,看書,音樂 🎉歡迎關注&#x1f50d…

Vue3 v-for循環獲取不到圖片路徑問題

解決辦法 <span>{{item.title}}</span> 通過本地靜態文件獲取img的地址即可展示圖片 url:"/src/assets/comImgs/txt1.png",

OpenGuass 之 where 1 = 0 處理流程代碼走讀

一. 前言 在OpenGuass中&#xff0c;如果where 條件中包含where 1 0 等固定為否條件的查詢語句&#xff0c;在生成執行計劃的時候&#xff0c;執行計劃是BaseResult類型&#xff0c;此類型的執行計劃不會進行物理數據掃描&#xff0c;如下所示&#xff1a; 對于非固定為否條件&…

【論文閱讀】多傳感器SLAM數據集

一、M2DGR 該數據集主要針對的是地面機器人&#xff0c;文章正文提到&#xff0c;現在許多機器人在進行定位時&#xff0c;其視角以及移動速度與車或者無人機有著較大的差異&#xff0c;這一差異導致在地面機器人完成SLAM任務時并不能直接套用類似的數據集。針對這一問題該團隊…

latex中\documentclass[preprint,review,12pt]{elsarticle}的詳細解釋

在LaTeX中&#xff0c;\documentclass 是一個命令&#xff0c;用于指定文檔所使用的文檔類。文檔類定義了文檔的總體結構、格式和樣式。elsarticle 是一個常用的文檔類&#xff0c;它主要用于在Elsevier出版的期刊上提交論文。 詳細解釋 \documentclass[preprint,review,12pt…

Autosar Appl介紹

AUTOSAR架構中的應用層 AUTOSAR 應用層構成AUTOSAR 架構中的最頂層,被認為對所有車輛應用至關重要。AUTOSAR 標準使用“組件”概念指定應用層實現。 在談論應用層實現時,應該考慮的三個最重要的部分是: AUTOSAR 應用軟件組件這些組件的 AUTOSAR 端口AUTOSAR 端口接口 AUTOS…