全球要聞:C語言基礎知識入門 C語言的具體結構
一、C語言基礎知識入門
C語言一經出現就以其功能豐富、表達能力強、靈活方便、應用面廣等特點迅速在全世界普及和推廣。C語言不但執行效率高而且可移植性好,可以用來開發應用軟件、驅動、操作系統等。C語言也是其它眾多高級語言的鼻祖語言,所以說學習C語言是進入編程世界的必修課!
【資料圖】
需 要 PDF版 和 詳 細 教 程 的可以看一下文章結尾
二、C語言的具體結構
簡單來說,一個C程序就是由若干頭文件和函數組成。
#include就是一條預處理命令, 它的作用是通知C語言編譯系統在對C程序進行正式編譯之前需做一些預處理工作。
函數就是實現代碼邏輯的一個小的單元。
三、主函數
一個C程序有且只有一個主函數,即main函數。
C程序就是執行主函數里的代碼,也可以說這個主函數就是C語言中的唯一入口。而main前面的int就是主函數的類型.printf()是格式輸出函數,這里就記住它的功能就是在屏幕上輸出指定的信息return是函數的返回值,根據函數類型的不同,返回的值也是不同的。\n是轉義字符中的換行符。(注意:C程序一定是從主函數開始執行的)
四、規范
一個說明或一個語句占一行,例如:包含頭文件、一個可執行語句結束都需要換行。函數體內的語句要有明顯縮進,通常以按一下Tab鍵為一個縮進。括號要成對寫,如果需要刪除的話也要成對刪除。當一句可執行語句結束的時候末尾需要有分號。代碼中所有符號均為英文半角符號。
五、程序解釋——注釋
注釋是寫給程序員看的,不是寫給電腦看的。
C語言注釋方法有兩種:
六、C的標識符
C語言規定,標識符可以是字母(A~Z,a~z)、數字(0~9)、下劃線_組成的字符串,并且第一個字符必須是字母或下劃線。在使用標識符時還有注意以下幾點:
標識符的長度最好不要超過8位,因為在某些版本的C中規定標識符前8位有效,當兩個標識符前8位相同時,則被認為是同一個標識符。標識符是嚴格區分大小寫的。例如Imooc和imooc 是兩個不同的標識符。標識符最好選擇有意義的英文單詞組成做到"見名知意",不要使用中文。標識符不能是C語言的關鍵字。想了解更多C語言關鍵字的知識。
七、變量及賦值
變量就是可以變化的量,而每個變量都會有一個名字(標識符)。變量占據內存中一定的存儲單元。使用變量之前必須先定義變量,要區分變量名和變量值是兩個不同的概念。
變量定義的一般形式為:數據類型 變量名;
多個類型相同的變量:數據類型 變量名, 變量名, 變量名…;
注意:在定義中不允許連續賦值,如int a=b=c=5;是不合法的。
變量的賦值分為兩種方式:
先聲明再賦值聲明的同時賦值
八、基本數據類型
C語言中,數據類型可分為:
基本數據類型構造數據類型指針類型空類型四大類
最常用的整型, 實型與字符型(char,int,float,double):
整型數據是指不帶小數的數字(int,short int,long int, unsigned int, unsigned short int,unsigned long int):
注:
int short int long int是根據編譯環境的不同,所取范圍不同。而其中short int和long int至少是表中所寫范圍, 但是int在表中是以16位編譯環境寫的取值范圍。另外 c語言int的取值范圍在于他占用的字節數 ,不同的編譯器,規定是不一樣。ANSI標準定義int是占2個字節,TC是按ANSI標準的,它的int是占2個字節的。但是在VC里,一個int是占4個字節的。
浮點數據是指帶小數的數字。
因為精度的不同又分為3種(float,double,long double):
九、格式化輸出語句
格式化輸出語句,也可以說是占位輸出,是將各種類型的數據按照格式化后的類型及指定的位置從計算機上顯示。
其格式為:printf("輸出格式符",輸出項);
當輸出語句中包含普通字符時,可以采用以下格式:
printf("普通字符輸出格式符", 輸出項);
注意:格式符的個數要與變量、常量或者表達式的個數一一對應
十、常量
在程序執行過程中,值不發生改變的量稱為常量。
mtianyan: C語言的常量可以分為直接常量和符號常量。
直接常量也稱為字面量,是可以直接拿來使用,無需說明的量,比如:
整型常量:13、0、-13;實型常量:13.33、-24.4;字符常量:‘a’、‘M’字符串常量:”I love imooc!”
在C語言中,可以用一個標識符來表示一個常量,稱之為符號常量。符號常量在使用之前必須先定義,其一般形式為
#define 標識符 常量值
#include#define POCKETMONEY 10 //定義常量及常量值int main(){ // POCKETMONEY = 12; //小明私自增加零花錢對嗎? printf("小明今天又得到%d元零花錢\n", POCKETMONEY); return 0; }
符號常量不可以被改變。
十一、自動類型轉換
數據類型存在自動轉換的情況. 自動轉換發生在不同數據類型運算時,在編譯的時候自動完成。
char類型數據轉換為int類型數據遵循ASCII碼中的對應值.
注:
十二、強制類型轉換
強制類型轉換是通過定義類型轉換運算來實現的。其一般形式為:
(數據類型) (表達式)
其作用是把表達式的運算結果強制轉換成類型說明符所表示的類型
在使用強制轉換時應注意以下問題:
數據類型和表達式都必須加括號, 如把(int)(x/2+y)寫成(int)x/2+y則成了把x轉換成int型之后再除2再與y相加了。轉換后不會改變原數據的類型及變量值,只在本次運算中臨時性轉換。強制轉換后的運算結果不遵循四舍五入原則。
十三、運算符號
C語言中運算符:
1.算術運算符
c語言基本運算符:
2.自增與自減運算符
自增運算符為++,其功能是使變量的值自增1自減運算符為--,其功能是使變量值自減1。
它們經常使用在循環中。自增自減運算符有以下幾種形式:
3.賦值運算符
C語言中賦值運算符分為簡單賦值運算符和復合賦值運算符
簡單賦值運算符=號了,下面講一下復合賦值運算符:
復合賦值運算符就是在簡單賦值符=之前加上其它運算符構成.
注意:復合運算符中運算符和等號之間是不存在空格的。
4.關系運算符
C語言中的關系運算符:
關系表達式的值是真和假,在C程序用整數1和0表示。
注意:>=, <=, ==, !=這種符號之間不能存在空格。
5.邏輯運算符
C語言中的邏輯運算符:
6.三目運算符
C語言中的三目運算符:?:,其格式為:
表達式1 ? 表達式2 : 表達式3; 執行過程是:
先判斷表達式1的值是否為真,如果是真的話執行表達式2;如果是假的話執行表達式3。
7.運算符大比拼之優先級比較
各種運算符號的順序:
優先級別為1的優先級最高,優先級別為10的優先級別最低。
十四、分支結構
1.簡單if語句
C語言中的分支結構語句中的if條件語句。
簡單if語句的基本結構如下:
if(表達式){執行代碼塊;}
其語義是:如果表達式的值為真,則執行其后的語句,否則不執行該語句。
注意:if()后面沒有分號,直接寫{}
2.if-else語句
簡單的if-else語句的基本結構:
語義是: 如果表達式的值為真,則執行代碼塊1,否則執行代碼塊2。
3.多重if-else語句
C語言中多重if-else語句,其結構如下:
語義是:依次判斷表達式的值,當出現某個值為真時,則執行對應代碼塊,否則執行代碼塊n。
注意:當某一條件為真的時候,則不會向下執行該分支結構的其他語句。
4.嵌套if-else語句
C語言中嵌套if-else語句。嵌套if-else語句的意思,就是在if-else語句中,再寫if-else語句。其一般形式為:
十五、循環結構
1.while循環
反復不停的執行某個動作就是江湖人稱的循環。
C語言中有三種循環結構,先看一下C語言while循環的結構
其中表達式表示循環條件,執行代碼塊為循環體。
while語句的語義是:計算表達式的值,當值為真(非0)時, 執行循環體代碼塊。
while語句中的表達式一般是關系表達或邏輯表達式,當表達式的值為假時不執行循環體,反之則循環體一直執行。一定要記著在循環體中改變循環變量的值,否則會出現死循環(無休止的執行)。循環體如果包括有一個以上的語句,則必須用{}括起來,組成復合語句。
2.do-while循環
C語言中的do-while循環,一般形式如下:
do-while循環語句的語義是:
它先執行循環中的執行代碼塊,然后再判斷while中表達式是否為真,如果為真則繼續循環;如果為假,則終止循環。因此,do-while循環至少要執行一次循環語句。
注意:mtianyan: 使用do-while結構語句時,while括號后必須有分號。
3.for循環
c語言中for循環一般形式:
它的執行過程如下:
執行表達式1,對循環變量做初始化;判斷表達式2,若其值為真(非0),則執行for循環體中執行代碼塊,然后向下執行;若其值為假(0),則結束循環;執行表達式3,(i++)等對于循環變量進行操作的語句;執行for循環中執行代碼塊后執行第二步;第一步初始化只會執行一次。循環結束,程序繼續向下執行。
注意:for循環中的兩個分號一定要寫
在for循環中:
表達式1是一個或多個賦值語句,它用來控制變量的初始值;表達式2是一個關系表達式,它決定什么時候退出循環;表達式3是循環變量的步進值,定義控制循環變量每循環一次后按什么方式變化。這三部分之間用分號 ; 分開。
使用for語句應該注意:
for循環中的“表達式1、2、3”均可不寫為空,但兩個分號(;;)不能缺省。省略“表達式1(循環變量賦初值)”,表示不對循環變量賦初始值。省略“表達式2(循環條件)”,不做其它處理,循環一直執行(死循環)。省略“表達式3(循環變量增減量)”,不做其他處理,循環一直執行(死循環)。表達式1可以是設置循環變量的初值的賦值表達式,也可以是其他表達式。表達式1和表達式3可以是一個簡單表達式也可以是多個表達式以逗號分割。表達式2一般是關系表達式或邏輯表達式,但也可是數值表達式或字符表達式,只要其值非零,就執行循環體。各表達式中的變量一定要在for循環之前定義。
3.三種循環比較
while, do-while和for三種循環在具體的使用場合上是有區別的,如下:
在知道循環次數的情況下更適合使用for循環;在不知道循環次數的情況下適合使用while或者do-while循環:如果有可能一次都不循環應考慮使用while循環如果至少循環一次應考慮使用do-while循環。但是從本質上講,while,do-while和for循環之間是可以相互轉換的。
4.多重循環
多重循環就是在循環結構的循環體中又出現循環結構。
在實際開發中一般最多用到三層重循環。
因為循環層數越多,運行時間越長,程序越復雜,所以一般用2-3層多重循環就可以了。另外不同循環之間也是可以嵌套的。
多重循環在執行的過程中,外層循環為父循環,內層循環為子循環,
**父循環一次,子循環需要全部執行完,直到跳出循環。**父循環再進入下一次,子循環繼續執行…
十六、結束語句
1.break語句
那么循環5次的時候,需要中斷不繼續訓練。在C語言中,可以使用break語句進行該操作.
使用break語句時注意以下幾點:
在沒有循環結構的情況下,break不能用在單獨的if-else語句中。在多層循環中,一個break語句只跳出當前循環。
2.continue語句
那么循環5次的時候,需要中斷后繼續訓練。在C語言中,可以使用continue語句進行該操作
continue語句的作用是結束本次循環開始執行下一次循環。
break語句與continue語句的區別是:
break是跳出當前整個循環,continue是結束本次循環開始下一次循環。
十七、局部與全局
C語言中的變量,按作用域范圍可分為兩種,即局部變量和全局變量。局部變量也稱為內部變量。局部變量是在函數內作定義說明的。其作用域僅限于函數內, 離開該函數后再使用這種變量是非法的。在復合語句中也可定義變量,其作用域只在復合語句范圍內。 全局變量也稱為外部變量,它是在函數外部定義的變量。它不屬于哪一個函數,它屬于一個源程序文件。其作用域是整個源程序。
十八、變量存儲類別
mtianyan: C語言根據變量的生存周期來劃分,可以分為靜態存儲方式和動態存儲方式。
靜態存儲方式:是指在程序運行期間分配固定的存儲空間的方式。靜態存儲區中存放了在整個程序執行過程中都存在的變量,如全局變量。 動態存儲方式:是指在程序運行期間根據需要進行動態的分配存儲空間的方式。動態存儲區中存放的變量是根據程序運行的需要而建立和釋放的,通常包括:函數形式參數;自動變量;函數調用時的現場保護和返回地址等。 C語言中存儲類別又分為四類:
自動(auto)、靜態(static)、寄存器的(register)外部的(extern)。
十九、內部函數與外部函數
在C語言中不能被其他源文件調用的函數稱謂內部函數 ,內部函數由static關鍵字來定義,因此又被稱謂靜態函數,形式為: static [數據類型] 函數名([參數]) 這里的static是對函數的作用范圍的一個限定,限定該函數只能在其所處的源文件中使用,因此在不同文件中出現相同的函數名稱的內部函數是沒有問題的。 在C語言中能被其他源文件調用的函數稱謂外部函數 ,外部函數由extern關鍵字來定義,形式為: extern [數據類型] 函數名([參數]) C語言規定,在沒有指定函數的作用范圍時,系統會默認認為是外部函數,因此當需要定義外部函數時extern也可以省略。 靜態變量只賦值一次
二十、數組初體驗
程序中也需要容器,只不過該容器有點特殊,它在程序中是一塊連續的,大小固定并且里面的數據類型一致的內存空間,它還有個好聽的名字叫數組。可以將數組理解為大小固定,所放物品為同類的一個購物袋,在該購 物袋中的物品是按一定順序放置的。
1.我們來看一下如何聲明一個數組:
數據類型 數組名稱[長度];
數組只聲明也不行啊,看一下數組是如何初始化的。說到初始化,C語言中的數組初始化是有三種形式的,分別是:
數據類型 數組名稱[長度n] = {元素1,元素2…元素n};數據類型 數組名稱[] = {元素1,元素2…元素n};數據類型 數組名稱[長度n]; 數組名稱[0] = 元素1; 數組名稱[1] = 元素2; 數組名稱[n-1] = 元素n;
我們將數據放到數組中之后又如何獲取數組中的元素呢?
獲取數組元素時: 數組名稱[元素所對應下標];
如:初始化一個數組 int arr[3] = {1,2,3}; 那么arr[0]就是元素1。
注意:
數組的下標均以0開始; 數組在初始化的時候,數組內元素的個數不能大于聲明的數組長度; mtianyan: 如果采用第一種初始化方式,元素個數小于數組的長度時,多余的數組元素初始化為0; 在聲明數組后沒有進行初始化的時候,靜態(static)和外部(extern)類型的數組元素初始化元素為0,自動(auto)類型的數組的元素初始化值不確定。
2.數組的遍歷
數組就可以采用循環的方式將每個元素遍歷出來,而不用人為的每次獲取指定某個位置上的元素,例如我們用for循環遍歷一個數組:
注意以下幾點:
最好避免出現數組越界訪問,循環變量最好不要超出數組的長度.C語言的數組長度一經聲明,長度就是固定,無法改變,并且C語言并不提供計算數組長度的方法。
由于C語言是沒有檢查數組長度改變或者數組越界的這個機制,可能會在編輯器中編譯并通過,但是結果就不能肯定了,因此還是不要越界或者改變數組的長度
3.數組作為函數參數
數組可以由整個數組當作函數的參數,也可以由數組中的某個元素當作函數的參數:
整個數組當作函數參數,即把數組名稱傳入函數中,例如:
數組中的元素當作函數參數,即把數組中的參數傳入函數中,例如:
數組作為函數參數時注意以下事項:
數組名作為函數實參傳遞時,函數定義處作為接收參數的數組類型形參既可以指定長度也可以不指定長度。數組元素作為函數實參傳遞時,數組元素類型必須與形參數據類型一致。
4.字符串與數組
C語言中,是沒有辦法直接定義字符串數據類型的,但是我們可以使用數組來定義我們所要的字符串。一般有以下兩種格式:
char 字符串名稱[長度] = “字符串值”;char 字符串名稱[長度] = {‘字符1’,‘字符2’,…,‘字符n’,’\0’};
注意:
[]中的長度是可以省略不寫的;采用第2種方式的時候最后一個元素必須是’\0’,’\0’表示字符串的結束標志;采用第2種方式的時候在數組中不能寫中文。在輸出字符串的時候要使用:printf(“%s”,字符數組名字);或者puts(字符數組名字);。
5.mtianyan:字符串函數
常用的字符串函數如下(strlen,strcmp,strcpy,strcat,atoi):
使用字符串函數注意以下事項:
strlen()獲取字符串的長度,在字符串長度中是不包括‘\0’而且漢字和字母的長度是不一樣的strcmp()在比較的時候會把字符串先轉換成ASCII碼再進行比較,返回的結果為0表示s1和s2的ASCII碼相等,返回結果為1表示s1比s2的ASCII碼大,返回結果為-1表示s1比s2的ASCII碼小strcpy()拷貝之后會覆蓋原來字符串且不能對字符串常量進行拷貝strcat在使用時s1與s2指的內存空間不能重疊,且s1要有足夠的空間來容納要復制的字符串
6.多維數組
多維數組的定義格式是: 數據類型 數組名稱[常量表達式1][常量表達式2]…[常量表達式n];
定義了一個名稱為num,數據類型為int的二維數組。其中第一個[3]表示第一維下標的長度,就像購物時分類存放的購物;第二個[3]表示第二維下標的長度,就像每個購物袋中的元素。
多維數組的初始化與一維數組的初始化類似也是分兩種:
數據類型 數組名稱[常量表達式1][常量表達式2]…[常量表達式n] = {{值1,…,值n},{值1,…,值n},…,{值1,…,值n}};數據類型 數組名稱[常量表達式1][常量表達式2]…[常量表達式n]; 數組名稱[下標1][下標2]…[下標n] = 值;
多維數組初始化要注意以下事項:
采用第一種始化時數組聲明必須指定列的維數。mtianyan: 因為系統會根據數組中元素的總個數來分配空間,當知道元素總個數以及列的維數后,會直接計算出行的維數;采用第二種初始化時數組聲明必須同時指定行和列的維數。
二維數組定義的時候,可以不指定行的數量,但是必須指定列的數量
二十一、C語言最核心的指針
說到指針,就不可能脫離開內存,學會指針的人分為兩種,一種是不了解內存模型,另外一種則是了解。
不了解的對指針的理解就停留在“指針就是變量的地址”這句話,會比較害怕使用指針,特別是各種高級操作。
而了解內存模型的則可以把指針用得爐火純青!
想學好C語言,很關鍵就是搞懂內存、指針、還有各種編譯鏈接,
1、內存本質
編程的本質其實就是操控數據,數據存放在內存中。
因此,如果能更好地理解內存的模型,以及 C 如何管理內存,就能對程序的工作原理洞若觀火,從而使編程能力更上一層樓。
大家真的別認為這是空話,我大一整年都不敢用 C 寫上千行的程序也很抗拒寫 C。
因為一旦上千行,經常出現各種莫名其妙的內存錯誤,一不小心就發生了 coredump...... 而且還無從排查,分析不出原因。
相比之下,那時候最喜歡 Java,在 Java 里隨便怎么寫都不會發生類似的異常,頂多偶爾來個 NullPointerException,也是比較好排查的。
直到后來對內存和指針有了更加深刻的認識,才慢慢會用 C 寫上千行的項目,也很少會再有內存問題了。(過于自信
「指針存儲的是變量的內存地址」這句話應該任何講 C 語言的書都會提到吧。
所以,要想徹底理解指針,首先要理解 C 語言中變量的存儲本質,也就是內存。
(1)內存編址
計算機的內存是一塊用于存儲數據的空間,由一系列連續的存儲單元組成,就像下面這樣,
每一個單元格都表示 1 個 Bit,一個 bit 在 EE 專業的同學看來就是高低電位,而在 CS 同學看來就是 0、1 兩種狀態。
由于 1 個 bit 只能表示兩個狀態,所以大佬們規定 8個 bit 為一組,命名為 byte。
并且將 byte 作為內存尋址的最小單元,也就是給每個 byte 一個編號,這個編號就叫內存的地址。
這就相當于,我們給小區里的每個單元、每個住戶都分配一個門牌號,在生活中,我們需要保證門牌號唯一,這樣就能通過門牌號很精準的定位到一家人。
同樣,在計算機中,我們也要保證給每一個 byte 的編號都是唯一的,這樣才能夠保證每個編號都能訪問到唯一確定的 byte。
(2)內存地址空間
上面我們說給內存中每個 byte 唯一的編號,那么這個編號的范圍就決定了計算機可尋址內存的范圍。
所有編號連起來就叫做內存的地址空間,這和大家平時常說的電腦是 32 位還是 64 位有關。
早期 Intel 8086、8088 的 CPU 就是只支持 16 位地址空間,寄存器和地址總線都是 16 位,這意味著最多對 2^16 = 64 Kb的內存編號尋址。
這點內存空間顯然不夠用,后來,80286 在 8086 的基礎上將地址總線和地址寄存器擴展到了20 位,也被叫做 A20 地址總線。
當時在寫 mini os 的時候,還需要通過 BIOS 中斷去啟動 A20 地址總線的開關。
但是,現在的計算機一般都是 32 位起步了,32 位意味著可尋址的內存范圍是 2^32 byte = 4GB。
所以,如果你的電腦是 32 位的,那么你裝超過 4G 的內存條也是無法充分利用起來的。
好了,這就是內存和內存編址。
(3)變量的本質
有了內存,接下來我們需要考慮,int、double 這些變量是如何存儲在 0、1 單元格的。
在 C 語言中我們會這樣定義變量:
int a = 999;char c = "c";
當你寫下一個變量定義的時候,實際上是向內存申請了一塊空間來存放你的變量。
我們都知道 int 類型占 4 個字節,并且在計算機中數字都是用補碼(不了解補碼的記得去百度)表示的。
999 換算成補碼就是:0000 0011 1110 0111
這里有 4 個byte,所以需要四個單元格來存儲:
有沒有注意到,我們把高位的字節放在了低地址的地方,那能不能反過來呢?
當然,這就引出了大端和小端。
像上面這種將高位字節放在內存低地址的方式叫做大端,反之,將低位字節放在內存低地址的方式就叫做小端。
上面只說明了 int 型的變量如何存儲在內存,而 float、char 等類型實際上也是一樣的,都需要先轉換為補碼。
對于多字節的變量類型,還需要按照大端或者小端的格式,依次將字節寫入到內存單元。
記住上面這兩張圖,這就是編程語言中所有變量的在內存中的樣子,不管是 int、char、指針、數組、結構體、對象... 都是這樣放在內存的。
2、指針是什么啥?
變量放在哪?上面我說,定義一個變量實際就是向計算機申請了一塊內存來存放。
那如果我們要想知道變量到底放在哪了呢?可以通過運算符&來取得變量實際的地址,這個值就是變量所占內存塊的起始地址。
PS: 實際上這個地址是虛擬地址,并不是真正物理內存上的地址
我們可以把這個地址打印出來
printf("%x", &a);
大概會是像這樣的一串數字:0x7ffcad3b8f3c
上面說,我們可以通過&符號獲取變量的內存地址,那獲取之后如何來表示這是一個地址,而不是一個普通的值呢?
也就是在 C 語言中如何表示地址這個概念呢?
對,就是指針,你可以這樣
int *pa = &a;
pa 中存儲的就是變量 a 的地址,也叫做指向 a 的指針。
在這里我想談幾個看起來有點無聊的話題:
當然可以,但是變量名是有局限的。
是變量地址的符號化,變量是為了讓我們編程時更加方便,對人友好,可計算機可不認識什么變量 a,它只知道地址和指令。
所以當你去查看 C 語言編譯后的匯編代碼,就會發現變量名消失了,取而代之的是一串串抽象的地址。
你可以認為,編譯器會自動維護一個映射,將我們程序中的變量名轉換為變量所對應的地址,然后再對這個地址去進行讀寫。
也就是有這樣一個映射表存在,將變量名自動轉化為地址:
a | 0x7ffcad3b8f3cc | 0x7ffcad3b8f2ch | 0x7ffcad3b8f4c....
說的好!
可是我還是不知道指針存在的必要性,那么問題來了,看下面代碼:
int func(...) { ... };int main() { int a; func(...);};
假設我有一個需求:
你說可以通過&取地址符號,將 a的地址傳遞進去:
int func(int address) { ....};int main() { int a; func(&a);};
這樣在func里就能獲取到 a的地址,進行讀寫了。
理論上這是完全沒有問題的,但是問題在于:
編譯器該如何區分一個 int 里你存的到底是 int 類型的值,還是另外一個變量的地址(即指針)。
這如果完全靠我們編程人員去人腦記憶了,會引入復雜性,并且無法通過編譯器檢測一些語法錯誤。
而通過int *去定義一個指針變量,會非常明確:這就是另外一個 int 型變量的地址。
編譯器也可以通過類型檢查來排除一些編譯錯誤。
這就是指針存在的必要性。
實際上任何語言都有這個需求,只不過很多語言為了安全性,給指針戴上了一層枷鎖,將指針包裝成了引用。
可能大家學習的時候都是自然而然的接受指針這個東西,但是還是希望這段啰嗦的解釋對你有一定啟發。
同時,在這里提點小問題:
既然指針的本質都是變量的內存首地址,即一個 int 類型的整數。
解引用
上面的問題,就是為了引出指針解引用的。
pa中存儲的是a變量的內存地址,那如何通過地址去獲取a的值呢?
這個操作就叫做解引用,在 C 語言中通過運算符 *就可以拿到一個指針所指地址的內容了。
比如*pa就能獲得a的值。
我們說指針存儲的是變量內存的首地址,那編譯器怎么知道該從首地址開始取多少個字節呢?
這就是指針類型發揮作用的時候,編譯器會根據指針的所指元素的類型去判斷應該取多少個字節。
如果是 int 型的指針,那么編譯器就會產生提取四個字節的指令,char 則只提取一個字節,以此類推。
下面是指針內存示意圖:
pa指針首先是一個變量,它本身也占據一塊內存,這塊內存里存放的就是 a變量的首地址。
當解引用的時候,就會從這個首地址連續劃出 4 個 byte,然后按照 int 類型的編碼方式解釋。
別看這個地方很簡單,但卻是深刻理解指針的關鍵。
舉兩個例子來詳細說明:
比如:
float f = 1.0;short c = *(short*)&f;
你能解釋清楚上面過程,對于 f變量,在內存層面發生了什么變化嗎?或者 c的值是多少?1 ?
實際上,從內存層面來說,f什么都沒變。
如圖:
假設這是f在內存中的位模式,這個過程實際上就是把 f的前兩個 byte 取出來然后按照 short 的方式解釋,然后賦值給 c。
詳細過程如下:
&f取得f 的首地址(short*)&f
上面第二步什么都沒做,這個表達式只是說 :
“噢,我認為f這個地址放的是一個 short 類型的變量”
最后當去解引用的時候*(short*)&f時,編譯器會取出前面兩個字節,并且按照 short 的編碼方式去解釋,并將解釋出的值賦給 c變量。
這個過程 f的位模式沒有發生任何改變,變的只是解釋這些位的方式。
當然,這里最后的值肯定不是 1,至于是什么,大家可以去真正算一下。
那反過來,這樣呢?
short c = 1;float f = *(float*)&c;
如圖:
具體過程和上述一樣,但上面肯定不會報錯,這里卻不一定。
為什么?
(float*)&c會讓我們從c的首地址開始取四個字節,然后按照 float 的編碼方式去解釋。
但是c是 short 類型只占兩個字節,那肯定會訪問到相鄰后面兩個字節,這時候就發生了內存訪問越界。
當然,如果只是讀,大概率是沒問題的。
但是,有時候需要向這個區域寫入新的值,比如:
*(float*)&c = 1.0;
那么就可能發生 coredump,也就是訪存失敗。
另外,就算是不會 coredump,這種也會破壞這塊內存原有的值,因為很可能這是是其它變量的內存空間,而我們去覆蓋了人家的內容,肯定會導致隱藏的 bug。
如果你理解了上面這些內容,那么使用指針一定會更加的自如。
3、結構體和指針
結構體內包含多個成員,這些成員之間在內存中是如何存放的呢?
比如:
struct fraction { int num; // 整數部分 int denom; // 小數部分};struct fraction fp;fp.num = 10;fp.denom = 2;
這是一個定點小數結構體,它在內存占 8 個字節(這里不考慮內存對齊),兩個成員域是這樣存儲的:
我們把 10 放在了結構體中基地址偏移為 0 的域,2 放在了偏移為 4 的域。
接下來我們做一個這樣的操作:
((fraction*)(&fp.denom))->num = 5; ((fraction*)(&fp.denom))->denom = 12; printf("%d\n", fp.denom); // 輸出多少?
上面這個究竟會輸出多少呢?自己先思考下噢~
接下來我分析下這個過程發生了什么:
首先,&fp.denom表示取結構體 fp 中 denom 域的首地址,然后以這個地址為起始地址取 8 個字節,并且將它們看做一個 fraction 結構體。
在這個新結構體中,最上面四個字節變成了 denom 域,而 fp 的 denom 域相當于新結構體的 num 域。
因此:
((fraction*)(&fp.denom))->num = 5
實際上改變的是 fp.denom,而
((fraction*)(&fp.denom))->denom = 12
則是將最上面四個字節賦值為 12。
當然,往那四字節內存寫入值,結果是無法預測的,可能會造成程序崩潰,因為也許那里恰好存儲著函數調用棧幀的關鍵信息,也可能那里沒有寫入權限。
大家初學 C 語言的很多 coredump 錯誤都是類似原因造成的。
所以最后輸出的是 5。
為什么要講這種看起來莫名其妙的代碼?
就是為了說明結構體的本質其實就是一堆的變量打包放在一起,而訪問結構體中的域,就是通過結構體的起始地址,也叫基地址,然后加上域的偏移。
其實,C++、Java 中的對象也是這樣存儲的,無非是他們為了實現某些面向對象的特性,會在數據成員以外,添加一些 Head 信息,比如C++ 的虛函數表。
實際上,我們是完全可以用 C 語言去模仿的。
這就是為什么一直說 C 語言是基礎,你真正懂了 C 指針和內存,對于其它語言你也會很快的理解其對象模型以及內存布局。
4、多級指針
說起多級指針這個東西,我以前上學的時候最多理解到 2 級,再多真的會把我繞暈,經常也會寫錯代碼。
你要是給我寫個這個:int ******p能把我搞崩潰,我估計很多同學現在就是這種情況??
其實,多級指針也沒那么復雜,就是指針的指針的指針的指針......非常簡單。
今天就帶大家認識一下多級指針的本質。
首先,我要說一句話,沒有多級指針這種東西,指針就是指針,多級指針只是為了我們方便表達而取的邏輯概念。
首先看下生活中的快遞柜:
這種大家都用過吧,每個格子都有一個編號,我們只需要拿到編號,然后就能找到對應的格子,取出里面的東西。
這里的格子就是內存單元,編號就是地址,格子里放的東西就對應存儲在內存中的內容。
假設我把一本書,放在了 03 號格子,然后把 03 這個編號告訴你,你就可以根據 03 去取到里面的書。
那如果我把書放在 05 號格子,然后在 03 號格子只放一個小紙條,上面寫著:「書放在 05 號」。
你會怎么做?
當然是打開 03 號格子,然后取出了紙條,根據上面內容去打開 05 號格子得到書。
這里的 03 號格子就叫指針,因為它里面放的是指向其它格子的小紙條(地址)而不是具體的書。
明白了嗎?
那我如果把書放在 07 號格子,然后在 05 號格子 放一個紙條:「書放在 07號」,同時在03號格子放一個紙條「書放在 05號」
這里的 03 號格子就叫二級指針,05 號格子就叫指針,而 07 號就是我們平常用的變量。
依次,可類推出 N 級指針。
所以你明白了嗎?同樣的一塊內存,如果存放的是別的變量的地址,那么就叫指針,存放的是實際內容,就叫變量。
int a;int *pa = &a;int **ppa = &pa;int ***pppa = &ppa;
上面這段代碼,pa就叫一級指針,也就是平時常說的指針,ppa就是二級指針。
內存示意圖如下:
不管幾級指針有兩個最核心的東西:
指針本身也是一個變量,需要內存去存儲,指針也有自己的地址
指針內存存儲的是它所指向變量的地址
這就是我為什么多級指針是邏輯上的概念,實際上一塊內存要么放實際內容,要么放其它變量地址,就這么簡單。
怎么去解讀int **a這種表達呢?
int ** a可以把它分為兩部分看,即int*和 *a,后面 *a中的*表示 a是一個指針變量,前面的 int*表示指針變量a
只能存放 int*型變量的地址。
對于二級指針甚至多級指針,我們都可以把它拆成兩部分。
首先不管是多少級的指針變量,它首先是一個指針變量,指針變量就是一個*,其余的*表示的是這個指針變量只能存放什么類型變量的地址。
比如int****a表示指針變量 a只能存放int***型變量的地址。
5、指針與數組
(1)一維數組
數組是 C 自帶的基本數據結構,徹底理解數組及其用法是開發高效應用程序的基礎。
數組和指針表示法緊密關聯,在合適的上下文中可以互換。
如下:
int array[10] = {10, 9, 8, 7};printf("%d\n", *array); // 輸出 10printf("%d\n", array[0]); // 輸出 10printf("%d\n", array[1]); // 輸出 9printf("%d\n", *(array+1)); // 輸出 9int *pa = array;printf("%d\n", *pa); // 輸出 10printf("%d\n", pa[0]); // 輸出 10printf("%d\n", pa[1]); // 輸出 9printf("%d\n", *(pa+1)); // 輸出 9
在內存中,數組是一塊連續的內存空間:
第 0 個元素的地址稱為數組的首地址,數組名實際就是指向數組首地址,當我們通過array[1]或者*(array + 1)去訪問數組元素的時候。
實際上可以看做 address[offset],address為起始地址,offset為偏移量,但是注意這里的偏移量offset不是直接和 address相加,而是要乘以數組類型所占字節數,也就是: address + sizeof(int) * offset。
學過匯編的同學,一定對這種方式不陌生,這是匯編中尋址方式的一種:基址變址尋址。
看完上面的代碼,很多同學可能會認為指針和數組完全一致,可以互換,這是完全錯誤的。
盡管數組名字有時候可以當做指針來用,但數組的名字不是指針。
最典型的地方就是在 sizeof:
printf("%u", sizeof(array));printf("%u", sizeof(pa));
第一個將會輸出 40,因為 array包含有 10 個int類型的元素,而第二個在 32 位機器上將會輸出 4,也就是指針的長度。
為什么會這樣呢?
站在編譯器的角度講,變量名、數組名都是一種符號,它們都是有類型的,它們最終都要和數據綁定起來。
變量名用來指代一份數據,數組名用來指代一組數據(數據集合),它們都是有類型的,以便推斷出所指代的數據的長度。
對,數組也有類型,我們可以將 int、float、char 等理解為基本類型,將數組理解為由基本類型派生得到的稍微復雜一些的類型,
數組的類型由元素的類型和數組的長度共同構成。而 sizeof就是根據變量的類型來計算長度的,并且計算的過程是在編譯期,而不會在程序運行時。
編譯器在編譯過程中會創建一張專門的表格用來保存變量名及其對應的數據類型、地址、作用域等信息。
sizeof是一個操作符,不是函數,使用 sizeof時可以從這張表格中查詢到符號的長度。
所以,這里對數組名使用sizeof可以查詢到數組實際的長度。
pa僅僅是一個指向 int 類型的指針,編譯器根本不知道它指向的是一個整數,還是一堆整數。
雖然在這里它指向的是一個數組,但數組也只是一塊連續的內存,沒有開始和結束標志,也沒有額外的信息來記錄數組到底多長。
所以對 pa使用 sizeof只能求得的是指針變量本身的長度。
也就是說,編譯器并沒有把 pa和數組關聯起來,pa僅僅是一個指針變量,不管它指向哪里,sizeof求得的永遠是它本身所占用的字節數。
(2)二維數組
大家不要認為二維數組在內存中就是按行、列這樣二維存儲的,實際上,不管二維、三維數組... 都是編譯器的語法糖。
存儲上和一維數組沒有本質區別,舉個例子:
int array[3][3] = {{1, 2,3}, {4, 5,6},{7, 8, 9}};array[1][1] = 5;
或許你以為在內存中 array數組會像一個二維矩陣:
1 2 34 5 67 8 9
可實際上它是這樣的:
1 2 3 4 5 6 7 8 9
和一維數組沒有什么區別,都是一維線性排列。
當我們像 array[1][1]這樣去訪問的時候,編譯器會怎么去計算我們真正所訪問元素的地址呢?
為了更加通用化,假設數組定義是這樣的:
int array[n][m]
訪問: array[a][b]
那么被訪問元素地址的計算方式就是: array + (m * a + b)
這個就是二維數組在內存中的本質,其實和一維數組是一樣的,只是語法糖包裝成一個二維的樣子。
6、 void 指針
想必大家一定看到過 void 的這些用法:
void func();int func1(void);
在這些情況下,void 表達的意思就是沒有返回值或者參數為空。
但是對于 void 型指針卻表示通用指針,可以用來存放任何數據類型的引用。
下面的例子就 是一個 void 指針:
void *ptr;
void 指針最大的用處就是在 C 語言中實現泛型編程,因為任何指針都可以被賦給 void 指針,void 指針也可以被轉換回原來的指針類型, 并且這個過程指針實際所指向的地址并不會發生變化。
比如:
int num;int *pi = # printf("address of pi: %p\n", pi);void* pv = pi;pi = (int*) pv; printf("address of pi: %p\n", pi);
這兩次輸出的值都會是一樣:
平??赡芎苌贂@樣去轉換,但是當你用 C 寫大型軟件或者寫一些通用庫的時候,一定離不開 void 指針,這是 C 泛型的基石,比如 std 庫里的 sort 函數申明是這樣的:
void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
所有關于具體元素類型的地方全部用 void 代替。
void 還可以用來實現 C 語言中的多態,這是一個挺好玩的東西。
不過也有需要注意的,不能對 void 指針解引用
比如:
int num;void *pv = (void*)#*pv = 4; // 錯誤
為什么?
因為解引用的本質就是編譯器根據指針所指的類型,然后從指針所指向的內存連續取 N 個字節,然后將這 N 個字節按照指針的類型去解釋。
比如 int *型指針,那么這里 N 就是 4,然后按照 int 的編碼方式去解釋數字。
但是 void,編譯器是不知道它到底指向的是 int、double、或者是一個結構體,所以編譯器沒法對 void 型指針解引用。
關于指針想寫的內容還有很多,這其實也只算是開了個頭,限于篇幅,以后有機會補齊以下內容:
二維數組和二維指針
數組指針和指針數組
指針運算
函數指針
動態內存分配: malloc 和 free
堆、棧
函數參數傳遞方式
內存泄露
數組退化成指針
const 修飾指針
標簽:
相關推薦:
精彩放送:
- []環球今日報丨中國“北斗”衛星導航系統——定位模塊需求介紹
- []世界快看:操作系統中死鎖的算法——銀行家算法
- []當前資訊!DirectSound能幫我們做什么?DirectSound開發指南
- []“流氓”劉邦戰勝英雄項羽的因素有哪些?詳情介紹
- []]]全球觀速訊丨st股票什么股
- []股票開戶需要多少錢
- []海昌海洋公園2022年營收同比下降近七成,將持續發展頂流IP
- []鏈家將27座城市轉為加盟模式?貝殼:消息不實,僅為小范圍合伙人模式
- []當前速訊:美達股份:公司生產的部分產品可在軍民融合領域進行應用,具體請以公司公告和定期報告為準
- []每日看點!國??萍迹褐袊某鞘熊壍澜煌ㄈ詣舆\行(無人駕駛)信號系統處于國際先進水平
- []【全球報資訊】悅榕集團2022財年總計63家酒店收官 計劃2025年擴張至113家
- []全球看熱訊:我愛我家副總裁何洋辭任
- []我愛我家:五八有限公司擬減持不超過2.74%股份 持股比例將低于5%
- []中國恒大披露重組進展
- []電科院:公司具體經營情況詳見以往定期報告
- []焦點訊息:航班老是臨時取消?民航局要出手了
- []環球新資訊:國泰君安醫藥一季報業績前瞻:業績復蘇環比趨勢明確
- []【速看料】中信建投:TOPCon電池、組件超額利潤有望擴大
- []眼看AI主題基金起高樓 “消費選手”仍在默默堅守
- []天天亮點!AI+元宇宙!Meta離夢想更進一步?
- []蘇州常熟2宗宅地將于5月5日出讓 起價合計5.4億元
- []昭衍新藥:公司會緊跟行業技術的發展變化,學習和借鑒相關技術在安評業務中的運用
- []環球百事通!中南建設前3月合同銷售額120.4億元 同比減少26.2%
- []消息!南昌中溢置業將轉讓杭州通原地產40%股權 底價8031.3萬元
- []亞通精工:公司未有應披露而未披露事項,股價漲跌受多種因素影響,股價波動是正常的市場交易行為
- []西安國際港務區掛牌2宗宅地面積共117畝 起始總價為7.894億元
- []財面兒丨越秀地產1-3月累計合同銷售額約人民幣438.33億元 同比上升約217.3%
- []當前視點!海容冷鏈:公司產品不應用于殯葬行業,公司產品應用于快速消費品行業的渠道建設
- []每日時訊!將優化調整高校兩成左右學科專業布點
- []【全球報資訊】合肥放開部分區域限購! 多孩家庭可買第3套住房
- []世界今日訊!鏈家欲在北京、上海以外城市轉為加盟模式?貝殼回應:無此計劃
- []每經熱評|當前并非出臺房產稅政策的好時機
- []天天訊息:一個月的寶寶很容易被驚嚇怎么辦_一個月的寶寶發育指標
- []【熱聞】怎樣取公積金
- []今日熱門!怎么取公積金
- []天天快看:交強險怎么用
- []貝殼:鏈家將27座城市轉為加盟模式消息不實 僅為小范圍合伙人模式
- []當前消息!滕哈赫:現在才是賽季真正的開始,輸給紐卡后我們要有積極回應
- []道達爾能源與伊拉克政府就100億美元天然氣開發項目達成一致
- []世界快資訊丨林斌辭任奧園美谷財務總監職務?江永標繼任
- []中南建設:中南城投減持212.03萬股 占所持股比例0.11%
- []天天百事通!中南建設前三月累計合同銷售金額120.4億元 同比降26.2%
- []胡泊、李強分別辭任南國置業聯席總經理、副總經理
- []萬達投資新增質押1930萬股萬達電影 累計質押6665萬股
- []環球今頭條!劉鑫獲任榮盛發展副總裁
- []全球熱文:廈門象嶼與河南能源集團簽訂戰略合作協議
- []環球最新:4月05日20時青海海東今天新增確診名單 4月05日20時青海海東疫情防控政策最新通知
- []當前視點!一半鄉土質樸,一半文藝先鋒,沙漠河流共生的小城,最美季節到了
- []全球熱門:戶用儲能系統有什么用,有哪些特點和應用?
- []全球看熱訊:長久物流設立儲能全資子公司!
- []天天亮點!不低于1GW!泰達股份聯手千泉實業投建光伏項目
- []30萬噸光伏玻璃硅砂提純項目環評
- []天天視點!超10GW!TCL中環單月出貨新突破
- []一彬科技:公司生產經營一切正常。公司對未來汽車產業的發展充滿信心
- []國際油價小跌,受制于美國制造業降溫,本周重頭戲待上演
- []焦點要聞:深圳到九江火車時刻表查詢_南昌到九江火車時刻表
- []醫道彤行,厚積薄發|2021道彤投資年度合伙人大會特寫
- []海淘的childlife大瓶鈣含防腐劑?專家建議嬰幼兒產品選購要謹慎
- []好好香鍋公司怎么樣
- []觀察:鴻路鋼構:鋼結構是綠色節能產品,是國家提倡并大力推廣的裝配式建筑的重要組成部分
- []基金經理猛追AI 但斌卻突然唱空:一旦被套 不知猴年馬月解套
- []關注:難道是真的?青海發現形狀怪異的遺骸,揭開大禹治水背后的真相!
- []世界微頭條丨維宏股份:整個Phoenix平臺包含了軟件和硬件兩個部分
- []簡訊:拜登:人工智能是否危險還有待觀察 但科技公司需為安全負責
- []世界聚焦:2023年Q1季度精選文章合集 | 商旅會獎賽道
- []觀速訊丨申請破產!暴跌90%
- []【全球新要聞】2023年Q1季度精選文章合集 | 在線旅游/分銷賽道
- []每日關注!四川宜賓:住房公積金最高貸款額度可達90萬元
- []全球快訊:伊戈爾:公司會根據客戶需求和業務開拓的情況提前布局或者調整相應的產能
- []越秀地產:一季度累計銷售約438億元
- []環球今日訊!合肥調整購房政策:部分區域放開限購
- []全球微資訊!全國春風地圖出爐 看看你那兒的四月天
- []環球關注:黃金大漲近2% 逼近歷史最高紀錄!金價為何持續大漲?專家解讀
- []當前快報:是否想念籃球?維金斯:我非常想念隊友們 期待與他們并肩作戰
- []外匯交易提醒:降息預期升溫,美元跌創近兩個月新低,新西蘭聯儲決議來襲,紐元續漲有望
- []周鴻祎突然離婚,要AI不要愛?董秘回應來了
- []accountnumber怎么讀_Accountnumber
- []4月5日財經早餐:美數據疲軟強化美聯儲放緩加息押注,金價站上2000美元/盎司大關創三十二個月新高
- []【世界聚看點】高達65%成本節約 施耐德電氣適配改造服務助企業把握“循環”機遇
- []銀行信貸投放不足原因_銀行信貸的作用
- []恒達集團控股2022年收入增加約3.4% 純利減74.3%至7780萬
- []環球速讀:車險傭金
- []看熱訊:三大保險
- []熱訊:壽險功用
- []當前資訊!聚焦中概 | 小鵬汽車跌幅擴大至7% 造車新勢力普跌
- []雙十原則
- []當前快看:烏龜冬眠是為了放水還是放沙?
- []天天快消息!周鴻祎與胡歡離婚 后者分得三六零4.46億股、對應市值近90億元
- []環球觀熱點:周度經濟觀察:斜率放緩的經濟復蘇
- []世界觀焦點:申通快遞:公司與阿里云合作,通過引入云原生技術實現了技術全面升級
- []全球短訊!深交所、滬交所4月8日全面實行注冊制交易業務通關測試
- []亞太藥業向下修正可轉債價格 律師:索賠宜趁早
- []假期安全注意事項內容圖片_假期安全注意事項內容
- []香山股份:目前尚無詳細的市場份額數據,更多詳情敬請留意公司官網及相關公告和定期報告
- []全球快看:秦安股份:4月3日公司高管劉宏慶減持公司股份合計1.16萬股
- []保利發展:房地產持續向好的基本面沒有變
- []世界快資訊:越秀地產前三月銷售438億?同比上升217%
- []當前聚焦:格力地產:珠海國資委同意公司收購免稅集團 并募資不超70億元
- B站注冊資本增幅400%至5億 目前由陳睿全資持股
- 光源資本出任獨家財務顧問 沐曦集成電路10億元A輪融資宣告完成
- 巨輪智能2021年上半年營收11.24億元 期內研發費用投入增長19.05%
- 紅棗期貨尾盤拉升大漲近6% 目前紅棗市場總庫存約30萬噸
- 嘉銀金科發布2021年Q2財報 期內凈利潤達1.27億元同比增長208%
- 成都銀行2021上半年凈利33.89億元 期內實現營收同比增長17.27億元
- 汽車之家發布2021年第二季度業績 期內新能源汽車品牌收入增長238%
- 中信銀行上半年實現凈利潤290.31億元 期末不良貸款余額706.82億元
- 光伏概念掀起漲停潮交易價格創新高 全天成交額達1.29億元
- 上半年生物藥大增45% 關鍵財務指標好轉營收賬款持續下降
- 天天觀點:保利發展:公司負債率連續三年下降 繼續保持穩健財務政策
- 保利發展:靈活安排推貨節奏?把握市場修復窗口
- 今日要聞!國家加強鐵礦石價格形勢分析研判和期現貨市場監管
- 世界熱資訊!寶馨科技:目前公司懷遠一期2GW異質結電池及組件項目正在加速推進中,預計年內投產
- 天天觀點:中交城投鄭州古滎城更項目獲得首筆融資
- 嶺南股份:公有云是云計算的主要形態。公司已與騰訊建立云計算、數字虛擬人、大數據等方面的戰略合作
- 世界短訊!西安土拍市場“活”了?
- 世界快報:湖北襄陽高新區2.08億售出65畝宅地 競得者為本地房企
- 今日熱訊:協創數據:公司存儲設備主要與聯想集團合作
- 【全球播資訊】三代人七十余載接力守護156座抗美援朝烈士墓
- 全球觀天下!每日互動:AIGC和ChatGPT都是融合多種AI技術的成果
- 天天滾動:神州高鐵:截至2023年3月31日,公司股東人數為91207
- 【天天新要聞】昭衍新藥:股價走勢受多方面因素的影響,還請謹慎投資
- 世界滾動:財面兒丨建發國際:前3月權益銷售額353.4億元,同比增長63.5%
- 全球實時:土地注冊處:香港3月樓宇買賣合約8599份 按年升124.6%
- 【天天新要聞】昆明公租房開發公司最終發行6億 品種一利率6.5%、品種二未發行
- 全球觀點:拼多多升級組織架構 聯合創始人趙佳臻出任聯席CEO搭檔陳磊
- 上海3月新建商品住宅成交面積環比增長94% 均價下跌2.8%
- 天天最資訊丨迪馬股份為江蘇2家子公司提供融資擔保 涉資8.04億元
- 滾動:狂飆910%!德國大儲市場崛起,戶儲地位岌岌可危?
- 新消息丨最新進展!中科云網5GW TOPCON電池項目一期簽署建設施工合同
- 焦點信息:煤矸石綜合利用與礦山生態修復的戰略思考
- 環球觀熱點:年產500萬噸!全球規模最大光伏砂項目成功簽約
- 最大涉水750mm 北京越野BJ60新增車型上市售24.58萬-27.68萬元
- 【天天播資訊】晶硅組件有什么作用和特點,有哪些種類?
- 環球旅訊+WiT新加坡主題沙龍開場演講:你好,中國!
- 天天報道:新地University Hill料最快4月底開售
- 環球速遞!萬通發展:萬通控股解質押270萬股股份 現持公司股份3.34億股
- 全球微動態丨建發房地產:10億元公司債券票面利率為4.25%
- 世界頭條:中核鈦白:公司第三期員工持股計劃并未在2023年3月14日進行大宗交易
- 全球觀速訊丨祥生控股首季銷售額54.19億元 同比下滑38.73%
- 國際油價走強,但多頭須警惕OPEC+最新減產的潛在負效用
- 恒基達鑫:公司始終密切關注橫琴粵澳深度合作區相關的措施和政策情況,望能充分利用和享受到政策帶來的紅利
- 當前滾動:顧家家居:截至3月末累計回購股份106.28萬股 總代價4187.73萬元
- 海新能科: 截至2023年03月31日,公司股東總人數為45,272名
- 中紅醫療:我國丁腈手套產品與馬來西亞相比有一定的成本優勢
- 經緯輝開:副董事長擬減持公司不超0.39%股份
- 富力地產:2022年度凈虧損157.79億元 預計今年可售貨值超1250億元
- 全球熱點!小摩增持萬物云39.86萬股 總金額約1406.76萬港元
- 全球速訊:嶸泰股份:我公司上市公司同行有旭升集團、愛柯迪、文燦股份等
- 新大正:正積極推進收購云南滄恒投資80%股權 尚存在不確定性
- 環球要聞:航天發展:截至2023年3月31日,航天發展股東戶數為179,101戶
- 當前快播:NYMEX原油仍上看83.17美元
- 4月4日福晶科技漲停分析:3D感應,中科院系,光通信概念熱股
- 會德豐合作盤MIAMI QUAY I暫累售49伙 套現4.8億港元
- 環球速讀:“20綠城03”將于4月13日提前摘牌 發行金額為10億元
- 天天資訊:4月4日中儲股份漲停分析:央企改革,快遞物流,國企改革概念熱股
- 4月4日四川黃金漲停分析:黃金概念熱股
- 環球今日訊!信達證券發布金陵飯店研報 年報點評:全年業績穩中有增 布局中高端 注重品牌打造
- 焦點!學習心得怎么寫?學習心得范本?
- 怎樣追女生?追女孩子的方法有哪些?
- 環球觀熱點:仙劍奇俠傳3有哪些歌曲?仙劍奇俠傳3所有歌曲匯總?
- 合山市景點有哪些?合山市景點介紹?
- 每日短訊:降雨量50毫米是怎么計算的?降雨量50毫米的計算方法?
- 當前資訊!生物圈2號為什么會失?。可锶Χ柺〉闹匾??
- 中青旅2022年營收64.17億元,旅行社業務虧損收窄
- 捷信金融怎樣貸款?捷信金融貸款條件有哪些?
- 環球熱議:lol英雄聯盟怎么觀戰?觀看別人的游戲戰斗方法?
- 每日看點!速干衣的特點有哪些?速干衣的主要功能是什么?
- 速訊:and1鞋子怎么樣?and1鞋子有哪些特點?
- 焦點簡訊:北京:加大老舊平房院落、老舊小區、危舊樓房和簡易樓等更新力度
- 世界熱文:常青股份:年報審計工作正在進行中,年報將于2023年4月26日披露
- 天天最新:山西大同:住房公積金貸款最高額度提至100萬元
- 環球今頭條!國際金價跌勢受限,美國數據再現疲軟,FED鷹派呼聲難響
- 美原油交易策略:需求預期接力,油價或延續漲勢
- 環球新消息丨蘇泊爾擬分紅24.40億元 控股股東SEB國際或分得20.12億元
- 千方科技:公司未參與您所提及的業務
- 當前快播:河南新鄉:住房公積金最高貸款額度升至65萬元
- 全球速讀:發改委:產業目錄引導橫琴加大對新興產業等的培育
- 焦點消息!年報橫評①| 這些物企表現最好!五大指標透視2022年指標之最
- 世界焦點!醫貝云服銷售總監陳小飛:醫貝云服伴隨著藥品和耗材供應鏈改革而誕生
- 孕婦補鈣用金丐,早吃早手藝
- 環球新資訊:甘化科工:截至2023年3月31日,公司股東人數為27,947戶
- 天天動態:上海新華聯國際獨棟商墅第三次流拍 起始價1.29億元
- 焦點精選!明陽智能:尊敬的公司公司對外信息披露均按照信息披露要求進行
- 環球時訊:德恩精工子公司擬與億盛房地產合作開發“濱江一號”項目 預計總投資約1.4億元
- 環球今日訊!二手房成交量“狂飆”,百城落地“帶押過戶”
- 環球焦點!國際金價短線下看1970美元
- 【天天熱聞】上海鋼聯:根據創業板上市公司相關規則,創業板上市公司無需披露季度業績預告
- 非凡舞蹈學院創辦人Jamila 王海青,打破自我,永不設限!善濟有約
- 股票進倉是什么意思
- 云南省餐飲行業協會交流座談會在文山舉行
- “AI”拼才會贏?16只基金單日飆漲超7% 公募基金開始密集大調倉
- 三圍怎么量
- 當前焦點!炒外匯為什么要拉人
- 用了“借錢三巨頭”之一的錢小樂,真實感受:靠譜!
- 手機炒股票用什么軟件最好
- 全球信息:收購瑞信后 瑞銀將取代摩根大通成為拉美最大財富管理公司
- 市場對黃金ETF和金幣的興趣激增,渣打稱這還只是開始!
- 天天熱點!現貨黃金交易策略:美元仍存下行風險,金價或震蕩上攻
- 對沖基金放棄看空押注,金銀正蓄勢待漲!
- 當前播報:長春城投10億元私募債券項目狀態更新為“已反饋”
- 全球看點:北京:土地出讓收入用于農業農村比例不低于7.5%
- 全球最新:【BT金融分析師】同程旅行月活躍用戶破2億,分析師稱其度過行業低潮
- 天天速看:【BT金融分析師】億航智能適航認證仍無進展,分析師稱其前景變得模糊
- 全球關注:央行調查:54.1%的居民預期下季度房價“基本不變”
- 世界看熱訊:黑石BREIT在3月收到45億元美元贖回請求 僅獲批6.66億美元
- 北信源:獲中國石油石化行業“科技進步一等獎” 樹立油庫安全生產行業典范
- 要聞速遞:利嘉閣:港3月整體樓宇買賣8612宗 20個月新高
- *ST科華:公司業務情況請關注公司于2022年3月23日披露的《2022年年度報告》