- 內(nèi)置類型的發(fā)展
C語言開始時只有char(8位)和int(16位)兩種,后來隨著發(fā)展又加入了short(16位)和long(32位)寄摆,此時谅辣,int可以是16位或者32位,依賴于平臺和后續(xù)的兼容性婶恼。再后來當64位出現(xiàn)時桑阶,long long(64位)又被添加進來,為了進行規(guī)范勾邦,對較小的一些類型的范圍就有了一些調(diào)整蚣录,逐漸穩(wěn)定為int32位,long可以有多種定義眷篇,可以是32位萎河,也可以是64位。
- 在C語言中蕉饼,double公壤、long、unsigned椎椰、int、char類型數(shù)據(jù)所占字節(jié)數(shù)
和機器字長及編譯器有關(guān)系沾鳄,所以慨飘,int、long int译荞、short int的寬度都可能隨編譯器而異瓤的。
但有幾條鐵定的原則(ANSI/ISO制訂的):
1. sizeof(short int)<=sizeof(int)
2. sizeof(int)<=sizeof(long int)
3. short int至少應為16位(2字節(jié))
4. long int至少應為32位(4字節(jié))
unsigned 是無符號的意思
例如:
16位編譯器
char :1個字節(jié)
char*(即指針變量): 2個字節(jié)
short int : 2個字節(jié)
int: 2個字節(jié)
unsigned int : 2個字節(jié)
float: 4個字節(jié)
double: 8個字節(jié)
long: 4個字節(jié)
long long: 8個字節(jié)
unsigned long: 4個字節(jié)
32位編譯器
char :1個字節(jié)
char*(即指針變量): 4個字節(jié)(32位的尋址空間是2^32, 即32個bit,也就是4個字節(jié)吞歼。同理64位編譯器)
short int : 2個字節(jié)
int: 4個字節(jié)
unsigned int : 4個字節(jié)
float: 4個字節(jié)
double: 8個字節(jié)
long: 4個字節(jié)
long long: 8個字節(jié)
unsigned long: 4個字節(jié)
64位編譯器
char :1個字節(jié)
char*(即指針變量): 8個字節(jié)
short int : 2個字節(jié)
int: 4個字節(jié)
unsigned int : 4個字節(jié)
float: 4個字節(jié)
double: 8個字節(jié)
long: 8個字節(jié)
long long: 8個字節(jié)
unsigned long: 8個字節(jié)
- NSInteger& NSUInteger
#import <objc/NSObjCRuntime.h>
源碼中對NSInteger和NSUInteger的定義如下:
/* NSObjCRuntime.h
Copyright (c) 1994-2012, Apple Inc. All rights reserved.
*/
#ifndef _OBJC_NSOBJCRUNTIME_H_
#define _OBJC_NSOBJCRUNTIME_H_
#include <TargetConditionals.h>
#include <objc/objc.h>
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
#define NSIntegerMax LONG_MAX
#define NSIntegerMin LONG_MIN
#define NSUIntegerMax ULONG_MAX
#define NSINTEGER_DEFINED 1
#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#else
#define NS_DESIGNATED_INITIALIZER
#endif
#endif
#endif
原來在蘋果的api實現(xiàn)中圈膏,NSInteger是一個封裝,它會識別當前操作系統(tǒng)的位數(shù)篙骡,自動返回最大的類型稽坤。
32位系統(tǒng)中NSInteger為int;64位系統(tǒng)中NSInteger為long糯俗。
You usually want to use NSInteger when you don't know what kind of processor architecture your code might run on, so you may for some reason want the largest possible int type, which on 32 bit systems is just an int, while on a 64-bit system it's a long.
- 取值范圍
//32bit
unsigned int 0~4294967295
int -2147483648~2147483647
unsigned long 和int一樣
long 和int一樣
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:1844674407370955161
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
//64bit
unsigned int 0~4294967295
int -2147483648~2147483647
unsigned long 和 unsigned long long一樣
long 和long long一樣
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:1844674407370955161
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
- 在32位系統(tǒng)中
int 占4個字節(jié)
long 占4個字節(jié)
NSInteger 是int的別名尿褪,占4個字節(jié)
long long 占8個字節(jié)
int32_t 是int的別名,占4個字節(jié)
int64_t 是long long的別名得湘,占8個字節(jié)
- 在64位系統(tǒng)中
int 占4個字節(jié)
long 占8個字節(jié)
NSInteger 是long的別名杖玲,占8個字節(jié)
long long 占8個字節(jié)
int32_t 是int的別名,占4個字節(jié)
int64_t 是long long的別名淘正,占8個字節(jié)
- 使用注意??
objective-c里摆马,蘋果的官方文檔中總是推薦用NSInteger或者是NSUInteger臼闻,這樣就不用考慮設(shè)備是32位還是64位了。
NSUInteger是無符號的囤采,即沒有負數(shù),NSInteger是有符號的述呐,所以NSUInteger類型不能給它賦負值。
比如以下這段代碼斑唬,a=-1的時候,是能進入循環(huán)的市埋。
//64-bit system
NSUInteger a = -1;
for(int i=0;i<a;i++){
NSLog(@"%d,%lu",i,(unsigned long)a);
break;
}
輸出:0,18446744073709551615
這時a的值其實等于18446744073709551615
(64位系統(tǒng)中)
還有NSUInteger和NSInteger和int都是基礎(chǔ)類型恕刘,是不能放入NSArray中的缤谎,需要轉(zhuǎn)換成NSNumber,應為NSNumber是類褐着,NSArray中只能放入類坷澡。
NSNumber是NSValue的一個子類,它是一個對象來存儲數(shù)字值包括bool型
1. 提供了一系列的方法來存儲char a signed or unsigned char, short int, int, long int, long long int, float, or double or as a BOOL
2. 它提供了一個compare:方法來決定兩個NSNumber對象的排序含蓉;
用以下NSNumber的類方法轉(zhuǎn)即可
(NSNumber *) numberWithChar: (char) value;
(NSNumber *) numberWithInt: (int) value;
(NSNumber *) numberWithFloat: (float) value;
(NSNumber *) numberWithBool: (BOOL) value;
或者使用@簡寫
@()代表NSNumber對象
@""代表NSString對象
@[]代表NSArray對象
@{}代表NSDictionary對象
將基本類型數(shù)據(jù)封裝到NSNumber中后频敛,就可以通過下面的實例方法重新獲取它:
- (char)charValue;
- (int)intValue;
- (float)floatValue;
- (BOOL)boolValue;
- (NSString *)stringValue;
由于long和NSInteger的字節(jié)數(shù)變了,所以在兼容的時候可能會導致溢出
對于一個11位的整數(shù)馅扣,它在64位系統(tǒng)中使用NSInteger或者long類型斟赚,是可以正常存儲的;如果是在32位系統(tǒng)中差油,它就溢出了拗军!
所以要保證某些較大的整數(shù)可以正常使用的話,就需要使用long long或者int64_t這樣的類型
另外在類型轉(zhuǎn)換的時候
例如 int64_t轉(zhuǎn)換成NSInteger蓄喇,在64位系統(tǒng)中是正常的
但在32位系統(tǒng)中就可能會導致溢出
參考:
int和NSInteger和long區(qū)別
iOS下int long longlong的取值范圍
iOS int long NSInteger 入門與兼容問題講解发侵,讓你秒懂
為什么long和int都是4字節(jié)
在C語言中,double妆偏、long刃鳄、unsigned、int钱骂、char類型數(shù)據(jù)所占字節(jié)數(shù)
iOS7----64位與32位 對比 數(shù)據(jù)類型
iOS-NSNumber對象介紹