通過C學Python(1)關於語言、數值類型和變量
強類型語言,不可能出現“程序執行出錯後仍可繼續執行,並且該錯誤導致的問題使後續執行可能出現任意行為”這類錯誤,這類錯誤的例子,如C裏的緩沖區溢出、Jump到錯誤地址。
弱類型語言,類型檢查更不嚴格,如偏向於容忍隱式類型轉換。例如C語言中int類型和double類型的隱式轉換。(個人認為int型和指針型的自由轉換,以及union中的一個int對4個char更能說明問題)
靜態類型語言,在編譯時就拒絕類型錯誤導致的問題
動態類型語言,在運行時才報出類型錯誤
C語言是弱類型、靜態類型
python是強類型,動態類型
數值類型:
整型 int
C中整型數據按照內存占用有好多種,python裏面只有一種
浮點型 float
C中有float和double兩種,python裏面只有一種
布爾型 bool
C中用宏TRUE和FALSE對應常量1和0,在python中True和False是屬於單獨的數據類型bool,但是內部實現依然是1和0,例如:1+True==2,1*False==0
復數型 (在python中用小寫 j ,表示虛部,用其他的字母不行)complex
C中沒有這個類型,需要自己定義一個結構體和一系列運算函數,但是C99/C++有添加這種數據類型。python中有這個數據類型,就可以很方便的進行復數運算
空類型 NoneType
C中用宏NULL表示空,對應常量0,在python中None是屬於單獨的數據類型NoneType,與常量0不同,不能與數值做運算,其實這也並不能算作數值類型
數值運算常用運算符:
+ - * %加、減、乘、取模,和C都一樣
/ 除,即使是兩個整型數據相除,得到的結果也可能是浮點數
// 整除,向下取整,和C語言中的整型相除效果一樣,沒有小數部分
** 乘方(冪),C對應的函數是pow,當然直接用乘方運算符用起來會更好看且易於理解
賦值運算符 :
= += -= *= /= //= 等... 和C的用法基本一致,python沒有++,自增1要用+=1
變量:
Python的變量無需事先聲明,無需指定類型,但是每個變量都是有類型的
Python中每個變量、常量都有一個id,可以通過內置函數id()來取得,通過這個函數可以看到一些特性:
實驗一:a = 2 ,b = 2 ,這時分別查看id(a)、id(b)、id(2)可以發現,他們三個的值是一樣的,就好像是三個指針指向了同一個地址,而這個地址上的數據就是2
實驗二:a = 1 ,id(a) , a = 2, id(a) ,這時可以看到,a的id發生了變化,也就是說這兩個a並不是同一個a了
通過這些現象來看,變量a、b並沒有用獨立的存儲空間去存放值,而更像是指針,指向了一塊內存區域,id()就是取出來目標地址,而在取變量a的值的時候,先通過id(a)找到目標地址,再把目標地址存放的數據取出來
經過我的測試實驗,True\False\None的id都是固定的,整型數據中從-5到256的id也是固定的,符合實驗一的現象,既分別給a和b賦同一個常量值,他們的id是一樣的,但是如果查出這個範圍,比如-6,進行下一個實驗
實驗三:a = -6,b = -6,這時id(a) == 2518190220080,id(b) == 2518190220496,兩個變量的id不同,但是值相同,說明他們的值分別另外開辟了空間,存儲了相同的值-6
實驗四:在實驗三的基礎上,b=a,這時id(a) == 2518190220080,id(b) == 2518190220080,他們的id相同,指向了同一個地址。
經過實驗,把-6換成浮點數、元組和列表,也符合實驗三和實驗四
實驗五:a=[1,2],b=a,a.append(3),這時,id(a)和id(b)相同,並且b的值也變成了[1,2,3],這驗證了上面說的,變量其實並沒有存放變量值,而是存放了目標地址,取變量值的時候,先去目標地址,再把值取出來。
通過C學Python(1)關於語言、數值類型和變量