计算机的核心部件:
- 中央处理器(CPU)
- 随机存储器(RAM)
- 相当于海量的“开关”,中央处理器可以打开、关闭、访问这些开关。
- 1 个开关保存一位(bit)的信息
- 8 个开关保存一个字节(Byte)的信息
-
1
代表(开) -
0
代表(关)
-
地址
- 内存是有数字编号的
- 通常地址用来指代某个特定字节的数据
32位CPU 和 64位CPU
- 地址的大小不同
- 32位CPU一次能处理32位,4个字节的数据
- 64位CPU一次能处理64位,8个字节的数据
如何获取数据起始位置的地址?
程序在计算机运行时,相关的一切数据都会保存在内存中,并有各自的地址。
运算符:&
说明符:%p
输出格式:十六进制
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
int i = 10;
printf("变量i, 内存地址是 %p\n", &i);
printf("函数main, 内存地址是 %p\n", main);
}
}
// 变量i, 内存地址是 0x7ffeee0b855c
// 函数main, 内存地址是 0x101b47ed0
指针
为什么非要使用指针呢?
当遇到比较复杂的数据时,就很有必要用指针来传递地址了
1.很容易地通过数据的起始地址,存取数据。
2.程序不一定能通过拷贝来传递数据。
3.程序一定能通过拷贝、直接传递数据的起始地址。
1.用指针保存地址
*星号,用于声明指针
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
int i = 10;
int *p = &i;
printf("变量i, 内存地址是 %p\n", &i);
printf("指针p, 内存地址是 %p\n", p);
}
}
// 变量i, 内存地址是 0x7ffee10b155c
// 指针p, 内存地址是 0x7ffee10b155c
2.通过地址访问数据
*星号,用于访问某个地址的数据
, 也成为去引用。
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
int i = 10;
int *p = &i;
printf("变量i, 内存地址是 %p\n", &i);
printf("指针p, 内存地址是 %p\n", p);
printf("指针p, 数据是 %d\n", *p);
}
}
// 变量i, 内存地址是 0x7ffeee52c55c
// 指针p, 内存地址是 0x7ffeee52c55c
// 指针p, 数据是 10
3.通过地址保存数据
*星号,用于赋值表达式中
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
int i = 10;
int *p = &i;
printf("变量i, 内存地址是 %p\n", &i);
printf("指针p, 内存地址是 %p\n", p);
printf("指针p, 数据是 %d\n", *p);
*p = 123;
printf("指针p, 数据是 %d\n", *p);
printf("变量i, 数据是 %d\n", i);
}
}
// 变量i, 内存地址是 0x7ffee9e5e55c
// 指针p, 内存地址是 0x7ffee9e5e55c
// 指针p, 数据是 10
// 指针p, 数据是 123
// 变量i, 数据是 123
不同类型数据占用字节大小
使用sizeof()
可以获取某个数据类型的大小
某个特定类型的数据会占用多少字节?
sizeof()会返回一个类型为size_t的数
说明符:%zu
输出单位:byte
指针长度:
- 4字节,32位CPU
- 8字节,64位CPU
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
int i = 10;
int *p = &i;
printf("变量i, 占用字节是 %zu\n", sizeof(i));
printf("指针p, 占用字节是 %zu\n", sizeof(p));
}
}
// 变量i, 占用字节是 4
// 指针p, 占用字节是 8
空指针(NULL)
“空”指针
不指向任何地址,用于明确表示该指针没有指向任何地址。
NULL就是0
(地址其实也是数字)
nil 和 NULL 是相等的
Objective-C 中使用nil
来代表该地址上没有对象
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
float *a;
a = NULL;
if (a) {
printf("a 不是 NULL");
} else {
printf("a 是 NULL");
}
}
}
// a 是 NULL
指针声明的代码规范
每次加深对指针的理解,保持良好的代码风格。
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
// 编译会通过,代码风格不够好
float *one; // 正确
float* two; // 错误
// C 语言,允许一行代码生成多个变量
float x, y, z;
// 同时声明b,c为指针
float* b, c; // 错误,(b指向float 的指针,c的类型是float)
float *b *c; // 正确
}
}
网友评论