.net調用c++方法時如何釋放c++中分配的內存_C/C++編程筆記:C語言編程知識要點總結!大一C語言知識點(全)...

f7d1e254ae92c7324ff348db9a7aa3ed.gif

一、C語言程序的構成

與C++、Java相比,C語言其實很簡單,但卻非常重要。因為它是C++、Java的基礎。不把C語言基礎打扎實,很難成為程序員高手。

1、C語言的結構

先通過一個簡單的例子,把C語言的基礎打牢。

a3de7368972d70467b4959f17af2f95d.png

C語言的結構要掌握以下幾點:

(1)C語言的注釋是/* ··· */,而不是//···,//是C++的單行注釋,有的C語言版本也認可。

(2)C語言區分大小寫,每句以分號結尾。

(3)C語言程序是從main函數開始的。函數的返回值如果缺省則為int,而不是void。

(4)函數必須用return來返回。即使void類型也不建議省略。

(5)使用函數時須包含相應的頭文件。自定義的頭文件用雙引號,C語言自身的頭文件用

2、main()函數的寫法與含義

main()的參數和返回值全部省略,這和上例含義相同。省略寫法是一種很不好的習慣。

238e45a5c3f039ad2e438ab0b8553606.png

main()的參數是一種不限個數的寫法,argc代表參數的個數,真正的參數是放在argv[]數組里面的。注意:當數組當參數用時,數組被降格為指針。初學者先照著樣子寫,以后小雅會詳細說明指針和數組的區別。

1d61c131627a1669175499dbce2407fb.png

3、頭文件的意義

每個C程序通常分為兩個文件。一個文件用于保存程序的聲明(declaration),稱為頭文件。另一個文件用于保存程序的實現(implementation),稱為定義(definition)文件。

C程序的頭文件以“.h”為后綴,C 程序的定義文件以“.c”為后綴。

頭文件的內容也可以直接寫C程序中,但這是很不好的習慣。許多初學者用了頭文件,卻不明其理。在此略作說明。

(1)通過頭文件來調用庫功能。在很多場合,源代碼不便(或不準)向用戶公布,只要向用戶提供頭文件和二進制的庫即可。用戶只需要按照頭文件中的接口聲明來調用庫功 能,而不必關心接口怎么實現的。編譯器會從庫中提取相應的代碼。

(2)頭文件能加強類型安全檢查。如果某個接口被實現或被使用時,其方式與頭文件中 的聲明不一致,編譯器就會指出錯誤,這一簡單的規則能大大減輕程序員調試、改錯的 負擔。

關于頭文件的內容,初學者還必須注意。

(1)頭文件中可以和C程序一樣引用其它頭文件,可以寫預處理塊,但不能寫語句命令。

(2)可以申明函數,但不可以定義函數。

(3)可以申明常量,但不可以定義變量。

(4)可以“定義”一個宏函數。注意:宏函數很象函數,但卻不是函數。其實還是一個申明。

(5)結構的定義、自定義數據類型一般也放在頭文件中。

(6)#include ,編譯系統會到C語言固定目錄去引用。#include "filename.h",系統一般首先在當前目錄查找,然后再去環境指定目錄查找。

4、好的風格是成功的關鍵

版本申明、函數功能說明、注釋等是C語言程序的一部分。不養成很好的習慣則不能成為C語言高手(專業人員)。

98b6b58624ad19d84cffd2ade6c3cae0.png

二、比較、邏輯、位運算符

只有類型相同(或C語言能自動轉換)的表達式才能比較,如果類型不同就必須用函數轉換。例如:判斷一字符串的長度是否等于10,就要用strlen()將字符串的長度求出來變成了整型,才能和10比較。

比較運算符只有6個,即:等于(==)、不等于(!=)、大于(>)、小于(=)、小于等于(<=)。比較運算符也叫關系運算符。

邏輯運算符只有3個,即:與AND(&&)、或OR(||)、非NOT(!)。

位運算符只有6個,即:與AND(&)、或OR(|)、非NOT(~)、異或XOR(^)、左移ShiftLeft(<>)。

三、數組

(1)數組名也是一變量名,定義時須指定類型和長度。

(2)長度可以方括號中直接指定,也可以通過賦值來間接指定。

(3)數組可以在定義時直接賦值,也可以定義時不賦值,之后再賦值。

(4)當使用超出范圍的值時,編譯不出錯,但運行會出錯。(上例運行時出錯后,選“忽略”后得到的結果)

數組的地址

弄清數組地址對使用數組有很大好處,另外,有的函數的參數是指針(如scanf函數),如果要用數組的某一元素作參數,就必須知道其地址。

48c65974b76cb4b162793a9cb3fb25a5.png

1.數組iArr是int類型,所以它的地址是按4字節遞增。

2.數組cArr是char類型,所以它的地址是按1字節遞增。

3.數組元素的地址是通過數組元素前面加“&”來取得。(如:&iArr[3])

4.數組名單獨使用時,代表該數組的首地址。(iArr等同于&iArr[0])(注意:以后使用指針會經常用到這一點)

四、字符數組和字符串的重定義

字符數組就是字符串嗎?有人說是,因為書上這么寫,教師也這么教的。小雅不敢說書上或教師們錯了,但至少可以說許多初學者都混淆了這兩個概念。因此,在這此將這2個概念再明確一下。

1.字符數組,完整地說叫字符類型的數組。字符數組不一定是字符串。

2.字符串是最后一個字符為NULL字符的字符數組。字符串一定是字符數組。

3.字符數組的長度是固定的,其中的任何一個字符都可以為NULL字符。

4.字符串只能以NULL結尾,其后的字符便不屬于該字符串。

5.strlen()等字符串函數對字符串完全適用,對不是字符串的字符數組不適用。

2b5a74ab1d21df0c4bbcd0675920c1ce.png

從上面例子看來,還要注意以下幾點:

(1)char sArr[] = "quanxue";這種方式,編譯時會自動在末尾增加一個NULL字符。

(2)NULL字符也就是'\0',在ASCII表中排在第一個,用16進制表示為0x00。

(3)sizeof()運算符求的是字符數組的長度,而不是字符串長度。

(4)strlen()函數求的是字符串長度,而不是字符數組。它不適用于字符串以外的類型。

(5)char sArr[] = "quanxue";也可以寫成char sArr[8] = "quanxue";(注意:是8而不是7)

字符數組和字符串數組的轉化

字符數組中插入一個NULL字符,NULL字符前面(包括NULL字符)就成了字符串,一般NULL字符插在有效字符的最后。

42f3c69f9c501cb99b082f1f0a3b2724.png

數組的輸入輸出『gets(),puts()』

getchar()和putchar()函數是單個字符的輸入輸出,gets()和puts()是字符串的輸入輸出,也是標準函數,在stdio.h中被定義。

五、指針

指針符號『*』和地址符號『&』

『&』符號是取變量的地址,『*』符號是取地址的內容(即:值)。兩個操作正好相反。例如:“&i”就是取變量i的地址,“*(&i)”就是取“&i”這個地址的值,其實就是變量i。即然如此,為什么還要定義指針呢?原來,用『&』所取到的地址,自身只能用而不能修改。因此,直接把『&』取到的地址放到指針變量中去,既然指針變量也是變量,這個變量就可以任意存放其它地址。

743c612889080e2ede951d746518abe3.png

指針變量的賦值和指針的賦值

上例中p是指針變量,*p是p的指針,p存放的是某個變量的地址,*p存放的是某個變量的值。當*p的內容改變時,p所指的變量的內容也發生改變,因為是同一個地址的存貯單元的值發生改變。同理,當p所指的變量的值發生改變時,*p的內容也隨之改變。

bdd4c1b8140bce2629c401f28fa5ceed.png

被初始化的是指針變量還是指針

上面2例,指針變量都是用的p,初學者不要認為只能用p,既然是變量,只要不違反命名規則都可以。當指針變量被定義時立即賦值,這時被賦值的是指針變量還是指針呢?下面這段程序請大家千萬注意!

74e98b6047f1d338b384547b9b838c92.png

(1)charstr[] ="http://www.quanxue.cn/";中str是數組變量,當地址賦給point之后,point[11]就是str[11],所以其內容可以改變。

(2)char*ptr ="http://www.51minge.com/";中賦值的性質和上面的str不同。這并不是將"http://www.51minge.com/"賦給*ptr指針,而是先定義一個常量"http://www.51minge.com/",這個常量是定義在“棧”里面,然后將這個常量的地址賦給ptr,而不是*ptr。常量是不能被修改的,因此ptr[13]也就出錯了。這是初學者經常犯的錯誤。

c22bb2dfc4d309f90445a4207cea147a.png

不賦值的指針和NULL

未賦值的指針變量是不能被使用的,其地址指向未不能使用的空間。建議定義時如果暫不使用,先賦NULL。為一個指針申請空間時,一定義要判斷其是否為空,因為分配內存失敗時返回NULL。不僅如此,甚至在使用指針時都應該判斷一下是否為空。

15b06527d1398f6f9672833fbb5ea66f.png

六、指針、數組和字符串

一、數組和指針的關系

下面仍然是初學者容易搞錯的地方。指針變量加n或減n,并不是地址加n或減n,而是當前所指的地址向后或向前跳n次所指的地址。

559dc2feabc07dfb50c324cd26c15c34.png


二、指針數組

char型的指針數組相當于二維字符數組,并不等于說指針數組可以直接轉化為二為字符數組,相反字符數組可以直接轉化為指針數組。因為二維字符數組的地址是連續的,而指針數組所指的元素不一定連續(如下的m1、m2、m3的地址可以不連續,長度也可以不一樣)。

92ef848ef503f07d0f6d9513d63fe29c.png

三、指向指針的指針

在第一章講main()函數的參數時,已經見過指針的指針,這和指針數組有相同的作用,但還是有細小的區別。指針數組可以在定義時直接初始化,而指向指針的指針不行。正如二維數組一樣,不指定第二維長度不能直接初始化一樣。即不能char str[][]={"...", "...", ...}

9f90f5a33c7834976e757dec7fd91b02.png

四、指針的長度

讓許多初學者遺憾的是,C語言沒有提供數組長度的函數,但可以用sizeof()運算符先求數組的總長度,再求出數組類型的長度,二者相除便得到數組的長度。C語言更大的一個遺憾便是,sizeof()對指針變量求值時,結果總是4,這是因為指針變量的內容是地址,地址總是4個字節來表示。

因此有經驗的編程人員,在用指針作參數時,一般總是同時多定義一個參數,來存放其長度。也就是指針和其長度同時傳遞過去。另外,數組長度如果事先知道,一般定義為常量。

2a191269fbab3fdcc6c5c333a4aa5920.png

七、為指針動態分配內存

C語言程序員要嚴防內存泄漏,這個“內存泄漏”就是由動態內存分配引起的。指針是C語言和其它語言的最大區別,也是很多人不能跨入C語言的一道門檻。既然指針是這么一個“危險”的壞東西,干嗎不取消它呢?

其實指針本身并沒有好壞,它只是一種操作地址的方法,學會了便可以發揮其它語言難以匹敵的功能,沒學會的話,只能做其它語言的程序員,也同樣發揮你的光和熱。小雅本人也在C語言門外徘徊多年,至今仍屬于初學者。

一、變量和數組可以通過指針來轉換

“int*x”中的x究竟是不是數組?光看這一句小雅無法告訴你,因為它既可表示單個變量內容,也可表示數組。下面是小雅專門為你準備的例子,理解之后,對動態分配時長度計算有好處。

be2f9486dd62c738b35e1233250a5f1c.png

二、動態分配內存

前面講到的指針,基本上將已經定義好的變量的地址賦給指針變量,現在要學的是向操作系統申請一塊新的內存。申請到的內存,必須在某個地方手動釋放,因此下面2個函數必須配對使用。malloc()和free(),都是標準函數,在stdlib.h中定義。

根據不同的電腦使用狀況,申請內存有可能失敗,失敗時返回NULL,因此,動態申請內存時,一定要判斷結果是否為空。malloc()的返回值類型是“void *”,因此,不要忘記類型轉換。(許多人都省略了。)

e28690660f472221fe24a7f03504da64.png

三、隱蔽的內存泄漏

內存泄漏主要有以下幾種情況:

(1)內存分配未成功,卻使用了它。

(2)內存分配雖然成功,但是尚未初始化就引用它。

(3)內存分配成功并且已經初始化,但操作越過了內存的邊界。

(4)忘記了釋放內存,造成內存泄露。

(5)釋放了內存卻繼續使用它。

下面的程序造成內存泄漏,想想錯在何處?如何修改?

43c3a45eab7057e67b1f42fdb076e0dc.png

四、對動態內存的錯誤觀念

有人對某一只在函數內使用的指針動態分配了內存,用完后不釋放。其理由是:函數運行結束后,函數內的所有變量全部消亡。這是錯誤的。動態分配的內存是在“堆”里定義,并不隨函數結束而消亡。

有人對某動態分配了內存的指針,用完后直接設置為NULL。其理由是:已經為NULL了,這就釋放了。這也是錯誤的。指針可以任意賦值,而內存并沒有釋放;相反,內存釋放后,指針也并不為NULL。

八、return和exit、assert的區別

return語句是結束當前函數。而exit是結束main()函數,即整個程序,一般都是在遇到非常錯誤時才調用exit()。assert()是一個宏定義,在assert.h中申明,用來在DEBUG方式診斷程序,當參數中的條件不成立時,中斷main()函數。建議多多使用assert()。

九、變量和函數

在函數之外定義的變量是全局變量,在函數內定義的變量是這個函數的局部變量。局部就是只能在當前函數內使用,而全局變量可以在任何一個函數中使用。

注意:一般而言,全局變量總是在所有函數之前定義,但如果某全局變量定義在兩個函數之間,則定義處后面的函數可以使用,而其前面函數不能使用。

有人說靜態變量相當于全局變量,這句話其實不對。全局變量變成靜態,就失去了靜態的意義,因此,靜態一般是加在局部變量上的。那么,究竟什么是靜態的局部變量呢?靜態變量隨函數的定義而定義,如果已經存在就延用,但并不隨函數的結束而消亡。在某一函數中定義的靜態局部變量,不能在其它函數使用。

當很多人編寫同一程序時,一般程序會被分割成幾個文件。當幾個人都定義了某一全局變量時,編譯時不出錯,Link時將出錯。解決這個問題的辦法:將其中一個定義原封不動,其余的定義前加上extend(即外部的定義)。

剛才所說是許多書上說的,小雅做了n次試驗,證明上述編譯時也不錯,Link時也不錯,也就是說extend完全是多余的。大概上面所說是幾十年前的版本吧。事實上與extend同列在一起的還有auto、regist等變量修飾符。auto是區別B語言的,早就沒用了,regist是將變量放到寄存器來運算,小雅認為基本沒有這種需要。

拆成多個文件,多次定義全局變量時要注意:

(1)變量的數據類型要一致。

(2)有長度的數組和沒定義長度的數組可以視為同一數據類型。

(3)數組和指針不能視為同一數據類型。

文章就分享到這里了,希望對大家有幫助!


自學C/C++編程難度很大,不妨和一些志同道合的小伙伴一起學習成長!

C/C++編程學習QQ群:1121833361,有問題需要交流或者想要C語言學習視頻可以加群一起成長哦!

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

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

相關文章

Django 使用 mysql 數據庫連接

啟用 mysql 數據庫連接 修改 app01 下的 __init__.py import pymysqlpymysql.install_as_MySQLdb() 修改 settings.py DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: django,USER: django,PASSWORD: django,HOST: 192.168.0.200,PORT: 3306,} } 測試 #生成同步…

Kinect開發筆記之四檢測并調試Kinect設備

之前我們已經裝好了Developer Toolkit 1.8&#xff0c;下面我們來做進一步的測試。首先到開始菜單中找到Kinect for Windows SDK v1.8&#xff0c;點擊其中的Developer Toolkit Browser v1.8.0。打開后&#xff0c;有許多東西&#xff0c;我們選擇最右邊的Tools來篩選一下&…

c語言雙引號和單引號的區別_Python中的單引號和雙引號有什么區別?

&#xfeff;在Python中使用單引號或雙引號是沒有區別的&#xff0c;都可以用來表示一個字符串。但是這兩種通用的表達方式可以避免出錯之外&#xff0c;還可以減少轉義字符的使用&#xff0c;使程序看起來更清晰。舉兩個例子&#xff1a;1、包含單引號的字符串定義一個字符串m…

mysql 開發基礎系列22 SQL Model(帶遷移事項)

一.概述 與其它數據庫不同&#xff0c;mysql 可以運行不同的sql model 下&#xff0c; sql model 定義了mysql應用支持的sql語法&#xff0c;數據校驗等&#xff0c;這樣更容易在不同的環境中使用mysql。 sql model 常用來解決下面幾類問題&#xff1a; (1) 通過設置sql mode, …

五月28學習筆記

<!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title></title> </head> <body> <!--鏈接標簽--> <!--核心屬性就是href 屬性值可以是一個跳轉的地址--&…

Kinect開發筆記之五使用PowerShell控制Kinect

這是第一次用MarkDown編輯器來寫博客&#xff0c;挺喜歡這種沒有任何格式舒服的編輯器&#xff0c;自由灑脫更加易讀&#xff0c;留一個不自然的自然段紀念下找到舒服的編輯器。 這次要記錄使用win7/win8內建的PowerShell來控制Kinect&#xff0c;改變Kinect的俯仰角度。 在我…

可轉債數據一覽表集思錄_可轉債股票數據一覽表

128107交科轉債720612061浙江交科-11.90%25113578全筑轉債754030603030全筑股份-1.26%3.84113573縱橫轉債754602603602縱橫通信5.79%2.7113577春秋轉債754890603890春秋電子-9.46%2.4123050聚飛轉債370303300303聚飛光電2.52%7.05110070凌鋼轉債733231600231凌鋼股份24.44%4.41…

國標流媒體H5實現無插件視頻監控按需直播

介紹 按需直播肯定是為了減少帶寬流量和服務器性能占用。安防行業GB28181協議天生就是按需播放的&#xff0c;有人請求播放時服務端才從設備端獲取設備的直播流或錄像視頻&#xff0c;停止播放時就會停止獲取視頻流。同時GB28181協議又是目前安防設備廠商都支持的統一的協議&am…

ipa 安裝包不用市場如果掃碼下載安裝 免費IOS安裝API

在做開發過程中可能會用于生成測試包的情況,不過測試包不能直接安裝,非常不方便,所以我提供給大家一下可通過鏈接下載安裝的方法也可以把鏈接生成二維碼掃碼下載 api地址: https://tool.bitefu.net/ipa/ 文件地址:http://tool.bitefu.net/showdoc/web/#/3 源碼下載:http://tado…

Kinect開發筆記之六Kinect Studio的應用

這一次我們來操作一下Kinect Studio&#xff0c;體驗一下它給我們帶來的功能。 首先我們需要打開Developer Toolkit Browser 1.8&#xff0c;打開后在默認情況下&#xff0c;光標是選擇在All選項卡上的&#xff0c;即我們現在所有Developer Toolkit Browser中的部件都可以看得…

antd picker 使用 如何_如何打造 Serverless JavaScript 全棧商業級應用?

2019 年底我們發布過一篇《O’Reilly 1500 份問卷調研&#xff1a;2019 年 Serverless 落地到底香不香&#xff1f;》&#xff0c;揭示了海外 Serverless 的落地情況&#xff0c;但中國 Serverless 的落地實踐分享相對較少&#xff0c;似乎誰都在喊 Serverless&#xff0c;誰都…

【Android Studio安裝部署系列】十三、Android studio添加和刪除Module 2

版權聲明&#xff1a;本文為HaiyuKing原創文章&#xff0c;轉載請注明出處&#xff01; 概述 新建、導入、刪除Module是常見的操作&#xff0c;這里簡單介紹下。 新建Module File——New——New Module... 選中Android Library 修改Library名稱 在項目工程中修改依賴 和添加下面…

Kinect開發筆記之七Visual Studio結合C#調控Kinect俯仰角度

總感覺自己前面啰啰嗦嗦寫了好多&#xff0c;卻一直都沒有使用用開發kinect的重型武器——Visual Studio。 那么本次我們就借助于Visual Studio&#xff0c;寫一個C#程序&#xff0c;連接Kinect并調用Kinect SDK標準函數庫來改變Kinect的俯仰角。 首先我們打開VS創建一個項目…

hadoop HDFS常用文件操作命令

命令基本格式: hadoop fs -cmd < args >1.ls hadoop fs -ls /列出hdfs文件系統根目錄下的目錄和文件 hadoop fs -ls -R /列出hdfs文件系統所有的目錄和文件 2.put hadoop fs -put < local file > < hdfs file >hdfs file的父目錄一定要存在&#xff0c;否則…

定量庫存控制模型_探索全面流動管理TFM 庫存控制與低減的理性策略

庫存乃萬惡之源庫存不僅占用了資金&#xff0c;還占用了各種管理性資源&#xff0c;形成了“財務性顯性成本“而且過多的庫存導致“緩沖區”的存在&#xff0c;還使得各類問題變得不那么緊迫&#xff0c;從而掩蓋了各類隱藏的問題&#xff0c;這被稱為“隱形成本”零庫存不僅做…

android studio更新之后打包遇到V1(Jar Signature)、 V2(Full APK Signature)問題

昨天更新了android studio 打包時遇到兩個勾選框&#xff0c;于是開始了解… 問題 剛開始默認是勾選 V2&#xff08;Full APK Signature&#xff09;&#xff0c;然后我就打包去測試先了&#xff0c;發現安裝失敗。之后發現與簽名有關系。 發現 android 7.0中引入了APK Signatu…

C#——一個簡單的文件管理器

最近在緊張的學習C#&#xff0c;說實話對C#之前沒有太多的接觸過&#xff0c;只知道C#的特性與java很相似&#xff0c;接觸了之后才發現C#跟java相比區別不是很多&#xff0c;但它是一門實現程序能力比Java還要好的語言&#xff08;僅代表個人觀點&#xff09;。 有許多新手在…

關于epoll,select,poll的理解

select: 輪詢fd_set 1.采用fd_set存儲fd&#xff08;fd_set通過數組位圖實現&#xff09; 2.每次調用select&#xff0c;都需要把fd集合從用戶態拷貝到內核態&#xff0c;fd越多開銷越大 3.每次調用select&#xff0c;都需要在內核遍歷傳遞進來的fd&#xff0c;開銷大(輪詢&…

kali linux超級用戶_如何優雅的在Linux上使用Powershell]

點擊上方“藍字”關注我們吧&#xff01;譯文聲明本文是翻譯文章&#xff0c;文章原作者 TJ Null文章來源&#xff1a;https://www.offensive-security.com原文地址&#xff1a;https://www.offensive-security.com/offsec/kali-linux-powershell-pentesting/譯文僅供參考&…

Laravel5.5 MySQL配置、讀寫分離及操作

2019獨角獸企業重金招聘Python工程師標準>>> Laravel 讓連接不同數據庫以及對數據庫進行增刪改查操作: 參考&#xff1a;http://laravelacademy.org/post/854.html 配置讀寫分離 應用的數據庫配置位于 config/database.php&#xff08;但是數據庫用戶及密碼等敏感信…