初次接觸C變數和基本類型的介紹
C是一種靜態類型語言。
這意味著任何變數都有一個關聯的類型,而且此類型在編譯時已知。
這與在Python、JavaScript、PHP和其他解釋語言中操作變量的方式非常不同。
在C中創建變量時,您必須在聲明時指定變量的類型。
在此示例中,我們使用類型int
對變量age
進行初始化:
int age;
變量名可以包含任何大小寫字母,可以包含數字和下劃線字符,但不能以數字開頭。AGE
和Age10
都是有效的變量名,1age
則無效。
您也可以在聲明時初始化變量,並指定初始值:
int age = 37;
定義變量後,您可以在程序代碼中使用它,並隨時更改其值,例如使用=
運算符,就像在age = 100;
中一樣,前提是新值具有相同的類型。
在這種情況下:
#include <stdio.h>
int main(void) {
int age = 0;
age = 37.2;
printf("%u", age);
}
編譯器將在編譯時拋出警告,並將十進制數字轉換為整數值。
C的內置數據類型包括int
、char
、short
、long
、float
、double
和long double
。讓我們更深入了解這些類型。
整數數字
C為我們提供以下類型來定義整數值:
char
int
short
long
大多數情況下,您可能會使用int
來存儲整數。但在某些情況下,您可能希望選擇另外3個選項之一。
char
類型通常用於存儲ASCII表中的字母,但也可以用來容納從-128
到127
的小整數。它至少占1個字節。
int
至少占2個字節。
short
至少占2個字節。
long
至少占4個字節。
正如您所看到的,對於不同環境,我們無法保證相同的值。我們只有一個指示。問題在於每種數據類型中可以存儲的確切數字取決於實現和體系結構。
我們保證short
不會比int
長,并且保證long
不會比int
短。
美國國家標準協會(ANSI)的C規範標準確定了每種類型的最小值,幸運的是,由於此規範,我們至少可以知道我們可以期望擁有的最小值。
如果您在Arduino上編程C,不同的開發板將具有不同的限制。
在Arduino Uno板上,int
存儲2字節值,範圍從-32,768
到32,767
。在Arduino MKR 1010上,int
存儲4字節值,範圍從-2,147,483,648
到2,147,483,647
。相差很大。
在所有Arduino板上,short
存儲2字節值,範圍從-32,768
到32,767
。long
占用4字節,范围从-2,147,483,648
到2,147,483,647
。
無符號整數
對於上述所有數據類型,我們可以在前面加上unsigned
以將範圍從0開始,而不是負數。在許多情況下,這可能是有意義的。
unsigned char
的範圍從0
到至少255
unsigned int
的範圍從0
到至少65,535
unsigned short
的範圍從0
到至少65,535
unsigned long
的範圍從0
到至少4,294,967,295
溢出問題
鑒於所有這些限制,可能會出現一個問題:我們如何確保我們的數字不超過限制?如果超過限制我們會得到什麼結果?
如果您具有unsigned int
數字為255,並將其增加,您將得到256作為結果。這是可以預料的。
如果您的unsigned char
數字為255,並將其增加,您將得到0作為結果。它會從初始可能值重新開始計算。
如果您的unsigned char
數字為255,並將其增加10,您將得到數字9
:
#include <stdio.h>
int main(void) {
unsigned char j = 255;
j = j + 10;
printf("%u", j); /* 9 */
}
如果您有一個帶符號值,行為是未定義的。它基本上會給您一個可以變動的巨大數字,就像在下面的例子中一樣:
#include <stdio.h>
int main(void) {
char j = 127;
j = j + 10;
printf("%u", j); /* 4294967177 */
}
換句話說,C不會保護您免於超過類型的限制。您需要自己解決這個問題。
在聲明錯誤類型時的警告
當您聲明變量並將其初始化為錯誤值時,gcc
編譯器(您可能正在使用的編譯器)應該會警告您:
#include <stdio.h>
int main(void) {
char j = 1000;
}
hello.c:4:11: warning: implicit conversion from 'int' to
'char' changes value from 1000 to -24
[-Wconstant-conversion]
char j = 1000;
~ ^~~~
1 warning generated.
它也會在直接賦值時警告您:
#include <stdio.h>
int main(void) {
char j;
j = 1000;
}
但如果您使用例如+=
增加數字,則不會有警告:
#include <stdio.h>
int main(void) {
char j = 0;
j += 1000;
}
浮點數
浮點類型可以表示的值比整數要多得多,還可以表示分數,這是整數無法做到的。
使用浮點數,我們將數字表示為10的幂的十進制數字乘以某個數。
您可能會看到浮點數寫成
1.29e-3
-2.3e+5
等奇怪的方式。
以下類型:
float
double
long double
用於表示帶有小數點的數字(浮點類型)。所有類型都可以表示正數和負數。
任何C實現的最低要求是float
可以表示介於10^-37和10^+37之間的範圍,通常使用32位來實現。
double
可以表示更大的一組數字。
long double
可以容納更多的數字。
與整數值一樣,具體數字取決於實現方式。
在現代Mac上,float
使用32位表示,具有24位有效位數的精度,8位用於編碼指數。
double
數字使用64位進行表示,具有53位有效位數的精度,11位用於編碼指數。
long double
類型使用80位進行表示,具有64位有效位數的精度,15位用於編碼指數。
在您的特定計算機上,您可以編寫一個程序來確定類型的具體大小:
#include <stdio.h>
int main(void) {
printf("char size: %lu bytes\n", sizeof(char));
printf("int size: %lu bytes\n", sizeof(int));
printf("short size: %lu bytes\n", sizeof(short));
printf("long size: %lu bytes\n", sizeof(long));
printf("float size: %lu bytes\n", sizeof(float));
printf("double size: %lu bytes\n", sizeof(double));
printf("long double size: %lu bytes\n", sizeof(long double));
}
在我的系統上,一台現代Mac上,它打印:
char size: 1 bytes
int size: 4 bytes
short size: 2 bytes
long size: 8 bytes
float size: 4 bytes
double size: 8 bytes
long double size: 16 bytes