iOS C、C++知识补漏
2021-10-22 本文已影响0人
山杨
- 共用体
共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[20];
};
int main( ) {
union Data data;
printf( "数据大小: %d\n", sizeof(data));
return 0;
}
结果输入是20
共用体占用的内存应足够存储共用体中最大的成员,也就是char str[20]。
- 位域
- 有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有 0 和 1 两种状态,用 1 位二进位即可。为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"。
- 所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
- 位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
struct bs{
int a:8;
int b:2;
int c:6;
}data;
data 为 bs 变量,共占两个字节。其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位。
#include <stdio.h>
#include <string.h>
struct
{
unsigned int age : 3;
} Age;
int main( )
{
Age.age = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
printf( "Age.age : %d\n", Age.age );
Age.age = 8; // 二进制表示为 1000 有四位,超出
printf( "Age.age : %d\n", Age.age );
return 0;
}
结果:
Sizeof( Age ) : 4
Age.age : 4
Age.age : 0
int main(){
struct bs{
unsigned a:1;
unsigned b:3;
unsigned c:4;
} bit,*pbit;
bit.a=1; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
bit.b=7; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
bit.c=15; /* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
printf("%d,%d,%d\n",bit.a,bit.b,bit.c); /* 以整型量格式输出三个域的内容 */
pbit=&bit; /* 把位域变量 bit 的地址送给指针变量 pbit */
pbit->a=0; /* 用指针方式给位域 a 重新赋值,赋为 0 */
pbit->b&=3; /* 使用了复合的位运算符 "&=",相当于:pbit->b=pbit->b&3,位域 b 中原有值为 7,与 3 作按位与运算的结果为 3(111&011=011,十进制值为 3) */
pbit->c|=1; /* 使用了复合位运算符"|=",相当于:pbit->c=pbit->c|1,其结果为 15 */
printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c); /* 用指针方式输出了这三个域的值 */
}
- 位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct k{
int a:1;
int :2; /* 该 2 位不能使用 */
int b:3;
int c:2;
};
- static和extern
变量如果没有用static
限制一般都是全局变量可以从外部直接访问,从安全上讲会有问题。
案例1
在YSObject.m文件中设置
MyKey
的值,这种没有任何限制的情况下默认是全局变量,看似没有暴露在YSObject.h文件中的全局变量却有被外部访问的风险。NSString *MyKey = @"testKey"; @implementation YSObject @end
在ViewController.m的文件中添加
MyKey
的声明extern NSString *MyKey;
extern NSString *MyKey; @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"MyKey = %@", MyKey); } @end
成功打印结果: MyKey = testKey
- 声明为局域变量:用
static
限制static NSString *MyKey = @"testKey";
- 声明为局域常量:用
static
和const
限制static NSString * const MyKey = @"testKey";
- 使用
static
声明的变量/常量,也可以暴露在YSObject.h文件中,外部导入该文件后,就可以直接访问到MyKey
的值。但外部访问的MyKey
是深拷贝出来的,因为内存地址和原来YSObject.h中的不同,所以在外部修改后对原文件(YSObject.h)内部的MyKey
值没有影响。案例2
在YSObject.h文件中声明
MyKey
的值extern NSString *MyKey; @interface YSObject : NSObject @end
在YSObject.m文件中设置
MyKey
的值NSString *MyKey = @"testKey"; @implementation YSObject @end
从外部引入YSObject.h文件后可以访问并且修改
MyKey
的值,并且因为是全局变量,只要修改MyKey
的值就会对全局产生影响,是非线程安全的。
- 如果
MyKey
需要被声明为一个全局常量,最好使用const
限制为不能修改,否则安全性也会降低extern NSString * const MyKey;
-
C++语法
struct __main_block_impl_0 {
NSString **name;
int age;
NSString *address;
__main_block_impl_0(NSString **_name, int _age, NSString *_address) : name(_name), age(_age), address(_address) {
}
};
等价于
struct __main_block_impl_0 {
NSString **name;
int age;
NSString *address;
__main_block_impl_0(NSString **_name, int _age, NSString *_address) {
name = _name;
age = _age;
address = _address;
}
};
-
C语法补充 - 变量声明
int a = 1;
等价于
auto int a = 1;
自动变量,离开作用域就销毁