Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

1. A domain

Information is generally accessed in bytes. In fact, sometimes it is not necessary to store information in one or more bytes, e.g., true/false values by 0 or 1. Yes, just 1 Bit. Bit field: A data structure that compacts data into bits and allows the programmer to manipulate the bits of the structure. Advantages of using bitfields:

  • The data unit can save storage space, which is especially important when the program needs thousands of data units
  • Location allows easy access to parts of an integer value to simplify program source code

Case study:

struct LGCar1 { 
    BOOL front; 
    BOOL back; 
    BOOL left; 
    BOOL right; 
};
Copy the code
  • LGCar1 contains four BOOL member variables of type fore, aft, left and right
struct LGCar1 car1; NSLog (@ LGCar1: % ld, sizeof (car1)); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- LGCar1:4Copy the code
  • It is 4 bytes, or 32 bits

Four true/false values divided by 4 bytes are a waste of space. Normally, 4 bits can be used to represent, accounting for 1 byte is “0000 1111”, use the lower 4 bits, respectively represent front, back, left, right so you can use the following code, use bitfields to save space

struct LGCar2 { 
    BOOL front : 1;
    BOOL back : 1; 
    BOOL left : 1; 
    BOOL right : 1; 
};
Copy the code
  • Syntax: Increment after a member variable: xRepresents the digit occupied by it
struct LGCar2 car2; NSLog (@ LGCar2: % ld, sizeof (car2)); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- LGCar2:1Copy the code

Run found that only 1 byte, 4 bits is enough

2. The commonwealth of

Struct: All variables are “co-existing”

  • Advantages: Strong inclusiveness, members do not influence each other
  • Disadvantages: waste of memory space, regardless of use, full allocation
struct LGTeacher1 { 
    char *name; 
    int age;
};
Copy the code
  • Define a structure containing name and age member variables
struct LGTeacher1 teacher1; teacher1.name = "Cooci"; teacher1.age = 18; NSLog(@"name: %s, age: % I, sizeof: %ld", Teacher1. name, Teacher1. age, sizeof(Teacher1)); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- name: Cooci, age: 18, sizeof: 16Copy the code
  • Member variables do not affect each other and account for 16 bytes

Union: Memory is shared among members. Variables are mutually exclusive

  • Advantages: Saving memory space, memory use is more delicate and flexible
  • Disadvantages: Less inclusive

Such as the following consortium:

union LGTeacher2 {
    char *name; 
    int age; 
};
Copy the code
  • Define a union containing name and age member variables
struct LGTeacher1 teacher1; teacher1.age = 18; teacher1.name = "Cooci"; NSLog(@"name: %s, age: % I, sizeof: %ld", Teacher1. name, Teacher1. age, sizeof(Teacher1)); -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- name: Cooci, age: 15934, sizeof: 8Copy the code

You can find

  • Members share memory, and only one member variable has a value. Age becomes a bad address because name is assigned
  • The size of the union is the size of the largest member variable
  • Unions are usually used in conjunction with bitfields

3. Use in projects

Open the lgcar. m file and write the following code: macro definition

#import "LGCar.h" #define LGDirectionFrontMask (1 << 0) #define LGDirectionBackMask (1 << 1) #define LGDirectionLeftMask  (1 << 2) #define LGDirectionRightMask (1 << 3)Copy the code

Define union + bitfield

@interface LGCar() {
    union { 
        char bits; 
        struct { 
            char front : 1;
            char back : 1; 
            char left : 1; 
            char right : 1; 
        };
    }_direction; 
} 

@end
Copy the code

Initialize the

- (instancetype)init { 
    self = [super init];
    if (self) {
        _direction.bits = 0b0000000000;
    }
    return self; 
}
Copy the code

Front getter/setter method

- (void)setFront:(BOOL)isFront { 
    if (isFront) { 
        _direction.bits |= LGDirectionFrontMask; 
    } else {
        _direction.bits |= ~LGDirectionFrontMask; 
    } 
    NSLog(@"%s",__func__); 
}
- (BOOL)isFront{ 
    return _direction.front;
}
Copy the code