這篇文章給大家聊聊關于c語言結構體怎么用,以及用scanf給結構體賦值對應的知識點,希望對各位有所幫助,不要忘了收藏本站哦。
c語言結構體定義和使用
struct為結構體關鍵字,tag為結構體的標志,member-list為結構體成員列表,其必須列出其所有成員;variable-list為此結構體聲明的變量。
結構體是C語言中聚合數據類型(aggregatedatatype)的一類。結構體可以被聲明為變量、指針或數組等,用以實現較復雜的數據結構。結構體同時也是一些元素的集合,這些元素稱為結構體的成員(member),且這些成員可以為不同的類型,成員一般用名字訪問。
c語言中結構編程是
c語言是一種結構化語言。它層次清晰,便于按模塊化方式組織程序,易于調試和維護。c語言的表現能力和處理能力極強。它不僅具有豐富的運算符和數據類型,便于實現各類復雜的數據結構。
它還可以直接訪問內存的物理地址,進行位(bit)一級的操作。由于c語言實現了對硬件的編程操作,因此c語言集高級語言和低級語言的功能于一體。既可用于系統軟件的開發,也適合于應用軟件的開發。此外,c語言還具有效率高,可移植性強等特點。因此廣泛地移植到了各類各型計算機上,從而形成了多種版本的c語言。
c語言,怎么將結構體寫入文件
一般有兩種方法.
以
structA{inta;floatf;chars[10];}m;
為例:
一種是寫文本文件
以"w"打開
fprintf(fp,"%d%f%s\n",m.a,m.f,m.s);
另一種是寫二進制文件.
以"wb"打開
fwrite(&m,sizeof(m),1,fp);
c語言結構化程序設計方法
C語言結構化程序設計,首先要分析問題,將所要解決的問題分解為不同的步驟,每個步驟可以編程為一個函數,在函數內部要認真分析本步驟應當如何進行結構設計,需要判斷還是循環,需要什么樣的數據結構,需要什么樣的參數,返回什么樣的值。
函數設計好以后,再通過合理的調用,就可以完成程序設計并解決一些復雜問題。
C語言中復制一個結構體只能使用memcpy的方法嗎感覺有些麻煩,有別的方法嗎
謝邀。
這個問題和我之前發的文章有些相似,上周我在我的C語言學習圈子里簡要介紹了一個小竅門,粗略來說就是使用C語言結構體的賦值語法,代替memcpy()語句,以精簡代碼,大致如下圖所示:
有讀者看到后,認為C語言結構體的賦值并不等價于memcpy,也有朋友評論說b=a是“淺拷貝”,還有讀者提到結構體賦值效率沒有memcpy高,那么b=a語句被執行后,究竟發生了什么呢?
編寫測試C語言代碼得到答案最簡單直接的方法就是實驗,因此這里給出一段較為完整的C語言代碼,用于測試結構體的賦值語句,如下所示。為了討論主題,下面C語言代碼比較精簡:
上面這段C語言代碼很簡單,main()函數定義了3個結構體變量a,b,c,其中a被初始化為{3,5},并通過賦值語句拷貝給b,memcpy()拷貝給c。考察a,b,c占用的內存里的值,從最終“拷貝效果”上分析賦值語句和memcpy()的異同。
查看內存值查看上述C語言程序中的變量a,b,c的值方法很多,最直接的方法就是使用printf()函數逐字節打印,不過這樣就略顯繁瑣了,使用GDB工具調試C語言程序更簡單些。
首先,輸入gcct.c-g編譯上述C語言代碼,得到可執行文件a.out。接著,就可以使用gdb調試了:
首先在main()函數處下斷點,然后輸入run命令讓C語言程序運行起來:
可以發現程序停在第10行了,此時變量a,b,c還沒有被賦值或者memcpy。我們先看一下結構體s的size,可以直接在gdb環境查看:
發現sizeof(structs)等于16,這主要是因為C語言編譯器為了提升效率,對結構體s的兩個成員做了內存對齊處理。所以,雖然char型的c成員實際上只需1個字節內存空間,但是因為成員l占用8字節內存空間,所以編譯器在c后面預留了7個字節。
讀者@Romi1984認為C語言結構體賦值拷貝和memcpy拷貝不等價,因為“賦值的話,對齊字節不會拷貝”。他的意思應該是c后面預留的7個字節不會被拷貝,那是不是如此呢?在執行b=a;語句之前,我們先來查看a,b,c在內存里的值:
能夠看出,此時變量a,b,c的內存值并不完全相同。輸入next命令,使C語言程序運行到第16行,也即return0;語句處,此時賦值語句以及memcpy語句都被執行完畢,再查看a,b,c的內存值,得到如下輸出:
發現變量a,b,c的值完全相同,包括結構體s的c成員后內存對齊的7個字節,這說明讀者@Romi1984說的“對齊字節不會被拷貝”是不準確的,至少就本例而言,C語言結構體s的賦值拷貝和memcpy拷貝效果上是等價的。
效率問題
雖然通過gdb查看內存值,我們發現C語言結構體的賦值拷貝和memcpy拷貝效果是等價的,但是,讀者@quser225816904認為,這兩種方式的效率是不一樣的。
那究竟是否如此呢?得到答案最直接的辦法就是衡量這兩條語句的執行時間。不過由于這一“執行時間”很短,難以計量,我們采取其他方法:輸入下面的命令,查看C語言程序的匯編代碼。
#objdump-dSa.out
從C語言程序的匯編代碼可以看出,b=a;和memcpy()語句都是4條mov語句,這說明兩種拷貝方式的效率相差無幾,所以讀者@quser225816904的說法也是不準確的。另外,從C語言程序的匯編代碼也能更直觀的看出b=a;和memcpy()是等價的。
讀者也可以通過多次執行b=a和memcpy語句,對比兩種拷貝方式的效率。
“深拷貝”和“淺拷貝”前面兩位讀者分別從執行效果和執行效率兩個角度質疑了C語言結構體賦值拷貝和memcpy拷貝的等價性,也有讀者認為賦值拷貝只是“淺拷貝”,那么究竟是否如此呢?
首先,先要明白“淺拷貝”和“深拷貝”概念,這兩個概念Java,C++,js等編程語言程序員應該比較熟悉,在C語言中倒是不怎么常提。細究這兩個概念的區別并不是本文的重點,所以這里粗略的對“淺拷貝”和“深拷貝”做如下區分,對于把變量a拷貝給b:
如果拷貝后,b的內容完全等于a,并且兩個變量在內存中是獨立的,則稱此次拷貝為“深拷貝”。如果靠背后,只是通過b能夠訪問a中的內容,a的內容改變時,b的“內容”也隨之改變,則稱此次拷貝為“淺拷貝”。
這樣看來,就本例而言,b=a;顯然是一次“深拷貝”,因為a,b在內存中彼此獨立,并且拷貝后,b的內容和a的內容完全相同。那C語言的結構體賦值拷貝一定是“深拷貝”嗎?我們將結構體s新增一個指針成員buf:
對a的初始化也做相應修改,相關C語言代碼如下,請看:
為了討論主題,上述C語言代碼沒有做錯誤處理。現在b=a;還是“深拷貝”嗎?讀者如果做了實驗,應該會發現,b的buf成員本身在內存中的確獨立于a的buf成員,但是它指向的內存卻與a的buf成員指向的內存是同一塊,所以這時b=a;不再是純粹的“深拷貝”了。
小結本節主要討論了C語言結構體的賦值語法可以用于拷貝,并針對之前讀者的幾個典型問題做了較為詳細的實例探討。不過,C語言是一門非常靈活的編程語言,可能同樣的一條語句,在不同的環境下執行結果是不一樣的,這一點本文最后的討論就是一個實例。應該明白,本文舉的例子僅是為了拋磚引玉,展示遇到問題該如何分析的方法,學習C語言,應該樂于做實驗嘗試才對。
歡迎在評論區一起討論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。
如果你還想了解更多這方面的信息,記得收藏關注本站。