1、變量
定義:創建一個對象,為這個對象分配一塊內存,并為它取一個名字,這個名字就叫做變量名;是對程序中數據的存儲空間的抽象。
存儲類型 數據類型 變量名;
描述:
一個變量可以通過不同種的方式來描述。
存儲期:
變量在內存中的保存時間
作用域:
程序的哪些部分通過變量名來使用變量
鏈接點:
程序的哪些部分通過變量名來使用變量
全局變量:也稱為外部變量,定義在函數體外部的變量,不屬于哪個函數,屬于整個
程序;
局部變量:也稱為內部變量,定義在函數體內部的變量,只能在函數內部使用;
存儲類型:auto register static extern
auto:聲明的變量是自動變量,聲明的變量存放在堆棧區,而且auto可以省略。
register:寄存器型,聲明的變量放在CPU內部的寄存器中,可以加快程序的運
行速度,如果申請不到,同auto;
定義與聲明的區別:定義分配內存,聲明不分配內存;
extern:
1、聲明的變量必須是全局變量;
2、編譯時必須同時編譯兩個文件;
3、聲明的變量必須被定義過。
static:
1、修飾局部變量,如果該局部變量沒有被初始化,其值為0,并且該局部變量只會被初始化一次;生命周期發生改變。
注:局部變量如果沒有被初始化,其值為隨機值;
2、修飾全局變量,該全局變量只能在本文件內使用;
3、修飾函數時,該函數只能在本文件內使用;
注:
1、具有外部鏈接的在其他文件使用前必須以exturn聲明
2、具有靜態存儲期的變量必須使用常量初始化(編譯階段獲得值)
-------與auto最大不同點是:static存儲類型的變量在內存中是以固定地址存放的,而不是以堆棧方式存放的;只要整個程序還在繼續運行靜態變量就不會隨著說明它的程序段的結束而消失,它下次再調用該函數,該存儲類型的變量不再重新說明,而且還保留上次調
用存入的數值。
2、動態存儲方式與靜態存儲方式
變量還有另一種屬性——存儲期(storage duration,也稱生命期)。存儲期是指變量在內存中的存在期間。這是從變量值存在的時間角度來分析的。存儲期可以分為靜態存儲期(static storage duration)和動態存儲期(dynamic storage duration)。這是由變量
的靜態存儲方式和動態存儲方式決定的。
所謂靜態存儲方式是指在程序運行期間,系統對變量分配固定的存儲空間。而動態存儲方式則是在程序運行期間,系統對變量動態地分配存儲空間。
先看一下內存中的供用戶使用的存儲空間的情況。這個存儲空間可以分為三部分,即:
程序區
靜態存儲區
動態存儲區
數據分別存放在靜態存儲區和動態存儲區中。全局變量全部存放在靜態存儲區中,在程序開始執行時給全局變量分配存儲單元,程序執行完畢就釋放這些空間。在程序執行過程中它們占據固定的存儲單元,而不是動態地進行分配和釋放。
在動態存儲區中存放以下數據:
函數形式參數。在調用函數時給形參分配存儲空間。
函數中的自動變量(未加static聲明的局部變量,詳見后面的介紹)。
函數調用時的現場保護和返回地址等。
對以上這些數據,在函數調用開始時分配動態存儲空間,函數結束時釋放這些空間。在程序執行過程中,這種分配和釋放是動態的,如果在一個程序中兩次調用同一函數,則要進行兩次分配和釋放,而兩次分配給此函數中局部變量的存儲空間地址可能是不相同
的。
如果在一個程序中包含若干個函數,每個函數中的局部變量的存儲期并不等于整個程序的執行周期,它只是整個程序執行周期的一部分。根據函數調用的情況,系統對局部變量動態地分配和釋放存儲空間。
在C++中變量除了有數據類型的屬性之外,還有存儲類別(storage class) 的屬性。存儲類別指的是數據在內存中存儲的方法。存儲方法分為靜態存儲和動態存儲兩大類。具體包含4種:自動的(auto)、靜態的(static)、寄存器的(register)和外部的(extern)。根據變量的存儲類別,可以知道變量的作用域和存儲期。對靜態局部變量的說明:
靜態局部變量在靜態存儲區內分配存儲單元。在程序整個運行期間都不釋放。而自動變量(即動態局部變量)屬于動態存儲類別,存儲在動態存儲區空間(而不是靜態存儲區空間),函數調用結束后即釋放。
為靜態局部變量賦初值是在編譯時進行值的,即只賦初值一次,在程序運行時它已有初值。以后每次調用函數時不再重新賦初值而只是保留上次函數調用結束時的值。而為自動變量賦初值,不是在編譯時進行的,而是在函數調用時進行,每調用一次函數重新給一次初值,相當于執行一次賦值語句。
如果在定義局部變量時不賦初值的話,對靜態局部變量來說,編譯時自動賦初值0(對數值型變量)或空字符(對字符型變量)。而對自動變量來說,如果不賦初值,則它的值是一個不確定的值。這是由于每次函數調用結束后存儲單元已釋放,下次調用時又重新另分
配存儲單元,而所分配的單元中的值是不確定的。
雖然靜態局部變量在函數調用結束后仍然存在,但其他函數是不能引用它的,也就是說,在其他函數中它是“不可見”的。
3、生命周期與作用域
局部變量:
生命周期:從定義開始,到該模塊結束
作用域:該模塊內
static修飾的局部變量:
生命周期:從定義開始,到整個程序結束
作用域:該模塊內
全局變量:
生命周期:從定義開始,到整個程序結束
作用域:該程序內
static修飾的全局變量:
生命周期:從定義開始,到整個程序結束
作用域:該文件內
注:全局變量如果沒有被初始化,其值為0;全局變量要慎用,原因有兩個:
1、命名重復
2、其他函數可能違背意圖將其值改變
4、類型轉換
1、隱式類型轉換
(1)低字節數向高字節數轉換
(2)有符號數向無符號數轉換(int ---> unsigned int)
2、強制類型轉換
(數據類型)變量名;
注:不管是隱式類型轉換還是強制類型轉換,實際上變量的類型并沒有發生變化,只是在運算的過程當中發生了轉換。
5、運算符
算術運算符、關系運算符、邏輯運算符、位運算符
1、算術運算符:+ - * / % ++ --
%:取模運算,小數沒有取模運算
++
int a = 5;
int b
= a++;
a = 7, b = 5, c = 7
注:
++在前,先賦值,后運算
++在后,先運算,后賦值
當++單獨成一條語句時,++在前和在后沒有區別;
2、關系運算符 > < >= <= == !=
注:
=為賦值運算符
==為等于號
if(5 == a)
3、邏輯運算符 && || !
表達式1 && 表達式2
表達式1和表達式2同時成立,整個表達式才成立,只要其中有一個不成立,整個表達式就為假
截斷法則:當&&左邊為假時,其值一定為假,所以&&右邊就不執行
表達式1 || 表達式2
||兩邊同時為假時,其值才為假,只要有一邊表達式為真,其值一定為真截斷法則:當||左邊為真時,其值一定為真,右邊不執行
4、位運算符:~ & | ^ >> <<
~00001111 11110000
&:00100010
10110000
00100000
1)、判斷某個數的某一位或某幾位是0還是1
10011011 判斷第四位是0還是1
& 00010000
00010000
2)、清除某個數的某一位或某幾位
10011011 清除第3到5位
& 11000111
10000011
3)、設置某個數的某一位或某幾位 (先清0,后設置)先與后或
10011011 設置第3到5位為101
& 11000111
| 00101000 10101011
^:兩個位進行異或時,相同為0,不同為1
一個數與0相異或,結果是其本身
翻轉某個數的某一位段
1100 0001 翻轉第3到5位
^ 00111000
11111001
>>:右移
1、溢出部分不要
2、高位:正數 高位補0
負數 補1
<<:左移
1、溢出時,溢出部分不要,右邊補0
2、如果是有符號數,可能會引起符號位的改變
5、逗號運算符:
表達式1,表達式2;
其求值過程是分別求兩個表達式的值,并以表達式2的值作為整個逗號表達
式的值。
表達式1,表達式2,表達式3,。。。。。。。。表達式n;
每個表達式都會執行,并把表達式n的值作為整個表達式的值。