美文网首页
《Objective-C 编程》11.结构、堆

《Objective-C 编程》11.结构、堆

作者: 独木舟的木 | 来源:发表于2020-03-16 00:17 被阅读0次

结构

编写程序时,可能要使用一个变量来保存多个相关的数据。C 语言中,可以使用结构(structure)来实现这个功能。每份数据称为结构的成员(member)。

#include <stdio.h>

// 声明 Person 结构,它包含两个成员变量。
struct Person {
    float heightInMeters;
    int weightInkilos;
};

int main(int argc, const char * argv[]) {
    
    // 声明类型为结构的变量时,需要使用关键字 struct
    struct Person mikey;
    // 通过点语法来访问结构的成员变量
    mikey.heightInMeters = 1.7;
    mikey.weightInkilos = 96;
    
    struct Person aaron;
    aaron.heightInMeters = 1.97;
    aaron.weightInkilos = 84;
    
    printf("Mikey 的升高是 %.2f。\n", mikey.heightInMeters);
    printf("Mikey 的体重是 %d。\n", mikey.weightInkilos);
    printf("Aaron 的升高是 %.2f。\n", aaron.heightInMeters);
    printf("Aaron 的体重是 %d。\n", aaron.weightInkilos);
    return 0;
}

说明:以上代码通过 struct 关键字声明了一个 Person 结构,它包含两个成员变量:名称为 heightInMetersfloat 类型变量,以及名称为 weightInkilosint 类型变量。

在声明类型为结构的变量时,每次都需要使用关键字 struct。为了简化输入,通常使用 typedef 关键字为某个结构声明一个新的类型。

#include <stdio.h>

// 声明 Person 结构
typedef struct {
    float heightInMeters;
    int weightInkilos;
} Person;

// 计算一个人的 BMI 指数
float bodyMassIndex(Person p) {
    return p.weightInkilos / (p.heightInMeters * p.heightInMeters);
}

int main(int argc, const char * argv[]) {
    
    Person mikey;
    mikey.heightInMeters = 1.7;
    mikey.weightInkilos = 96;
    
    Person aaron;
    aaron.heightInMeters = 1.97;
    aaron.weightInkilos = 84;
    
    float bmi;
    // 将 Person 结构传给一个函数
    bmi = bodyMassIndex(mikey);
    printf("Mikey 的 BMI 指数是:%.2f。\n", bmi);
    
    bmi = bodyMassIndex(aaron);
    printf("Aaron 的 BMI 指数是:%.2f。\n", bmi);
    return 0;
}

  • 中的内存会在调用函数时由系统自动分配,并在函数结束后自动释放。这也是局部变量常被称为自动变量的原因。
  • :函数中的局部变量。
  • 缓冲区(buffer):表示一块连续的内存,缓冲区来自特定的内存区域——(heap),堆和栈是分开的。
  • 在堆上,缓冲区独立于任何函数的栈。因此,它可以在多个函数中使用。
  • 使用 malloc() 函数可以得到一块内存缓冲区。当程序不再使用这块缓冲区时,可以调用 free() 函数以释放相应的内存,将其返还给堆。

示例:为程序分配一块至少存放 1000 个 float 变量的内存。

#include <stdio.h>
#include <stdlib.h> // malloc 和 free 函数都来自 stdlib

int main(int argc, const char * argv[]) {
    
    // 声明指针变量
    float *startOfBuffer;
    
    // 从堆分配指定字节数的内存
    // 通过 sizeof() 函数获得 1 个缓冲区的准确大小
    startOfBuffer = malloc(1000 * sizeof(float));
    
    // ......使用缓冲区......
    
    // 释放之前分配到的内存,使之能够被重新使用
    free(startOfBuffer);
    
    // 将指针变量赋值为空
    startOfBuffer = NULL;

    return 0;
}

以上示例中,startOfBuffer 是一个指针,它指向缓冲区中的第一个浮点数,如下图所示:

我们也可以在堆中为结构分配一块缓冲区。例如,在堆中为 Person 结构分配内存的代码如下:

#include <stdio.h>
#include <stdlib.h>

// 声明 Person 结构
typedef struct {
    float heightInMeters;
    int weightInkilos;
} Person;

// 计算一个人的 BMI 指数
float bodyMassIndex(Person *p) {
    return p->weightInkilos / (p->heightInMeters * p->heightInMeters);
}

int main(int argc, const char * argv[]) {
    
    // 为一个 Person 结构分配内存,
    // 现在 mikey 是一个指针,指向一块连续的内存区域(堆中的一个缓冲区)
    Person *mikey = (Person *)malloc(sizeof(Person));
    
    // 为一个 Person 结构分配内存
    mikey->heightInMeters = 1.7;
    mikey->weightInkilos = 96;
    
    // 计算并输出 BMI 指数
    float bmi = bodyMassIndex(mikey);
    printf("Mikey 的 BMI 指数是:%.2f。\n", bmi);

    // 释放之前分配到的内存,使之能够被重新使用
    free(mikey);
    
    // 将指针变量赋值为空
    mikey = NULL;
    return 0;
}

注意到,p->weightInkilos 的作用是:先获取指针 p 指向的数据结构,然后返回该结构的成员变量 weightInkilos,如下图所示:

也可以理解为:获取对象中的一个属性的值。

堆中的结构,是 Objective-C 对象的实现基础

相关文章

网友评论

      本文标题:《Objective-C 编程》11.结构、堆

      本文链接:https://www.haomeiwen.com/subject/gtuiehtx.html