1、结构体、柔型数组以及union

1、结构体:用户自己建立不同数据类型组成的组合型的数据结构。

struct student  
{
	成员列表
};
struct student student1;

// struct 为声明结构体类型的关键字,student为结构体名
// struct student 为一个结构体类型
// student1 为 struct student 类型的变量

或者在定义结构体类型的同时定义结构体变量:

struct student  
{
	成员列表
}student1,stuednt2;

比较 struct 和 typedef struct:

typedef struct Student            //也可以写成typedef struct 
{
	int a;
}Stu;

typedef 本质是对已有的类型进行重命名,对比 typedef int INT32,所以在这里Stu 等同于 struct Student。这两个都代表相同的数据类型,就可以用Stu代表struct Student结构体类型,所以如果要定义结构体变量,直接Stu student1即可。(Stu 用来定义变量,Stu 是类型而不是变量)

但是对于

struct student  
{
	成员列表
};  

如果我们要定义一个结构体变量就必须 struct student student1这样才算定义了一个结构体变量,因为struct student 才是结构体类型

空结构体:在 vs2015 里面不允许空结构体的存在,但是在 gcc 编译器把空结构体的大小定义为0,这是个灰色地带。

2、柔型数组

— 柔型数组即数组大小待定的数组
— C语言中可以由 结构体产生柔型数组
— C语言中结构体的最后一个元素大小未知的数组
— 柔型数组所占用的字节大小仅仅和长度的类型有关

好处:动态决定数组的长度

#include <stdio.h>
struct SoftArray
{
	int len;
	int array[];
};
int main()
{
	printf("%d\n", sizeof(struct SoftArray));	//4,表明柔型数组结构体大小只有4个字节
	return 0;
}

基本格式:

struct SoftArray
{
	int len;
	int array[];
};
...
struct SoftArray* sa = NULL;
sa = (struct SoftArray* )malloc(sizeof(struct SoftArray)+sizeof(int)*5);
sa->len = 5;
  • 为什么指向动态内存的指针类型为结构体指针类型?
    因为我们可以通过这个指针来给结构体里面的长度赋值。

实例程序:

#include <stdio.h>
#include <malloc.h>
struct SoftArray
{
	int len;
	int array[];
};

struct SoftArray* creat_soft_array(int length)
{
	struct SoftArray* ret = NULL;
    if(length > 0)
    {
        ret = (struct SoftArray*)malloc(sizeof(struct SoftArray) + sizeof(int) * length);
        if(ret != NULL)
        {
            ret->len = length;
        }
    }
    return ret;
}

void free_soft_array(struct SoftArray* sa)
{
	free(sa);
}

void func(struct SoftArray* sa)
{
	int i = 0;
	if (NULL != sa)
	{
		for (int i = 0; i < sa->len; i++)
		{
			sa->array[i] = i + 1;
		}
	}
}
int main()
{
	int i = 0;
	struct SoftArray *sa = creat_soft_array(10);
	func(sa);
	for (i = 0; i < sa->len; i++)
	{
		printf("%d\n", sa->array[i]);
	}
	free_soft_array(sa);
	return 0;
}

3、C语言中的联合体 union

联合体里面可以定义多个成员变量,在任何时刻,只有一个成员变量有效。union是只分配最大成员的空间,而且所有的成员共享这个空间.

比如说空间里面已经有一个 int 值,你一个 char 的只能是里面一个字节的那个值。

#include <stdio.h>
struct A
{
	int a;
	int b;
	int c;
};
union B
{
	int a;
	int b;
	int c;
};
int main()
{
	printf("%d\n", sizeof(struct A));         // 12
	printf("%d\n", sizeof(union B));          // 4     3个int值共享这4个字节
	return 0;
}

union的注意事项:union的使用受系统大小端的影响,我们一般的电脑系统都是小端系统,union 和 struct 差不多,就是意义不同。

在小端系统里,1被存储在低地址上面;
在大端系统里,1被存储在高地址上面。

小端模式,低地址存储低位数据;大端模式,低地址存储高位数据。
在这里插入图片描述
例题:

#include <stdio.h>
union A
{
   int i;
   char c[2];
 }a;

int main()
{
    a.c[0] = 10;
    a.c[1] = 1;
    printf("i = %d\n",a.i);
    return 0;
}

分析:10 == 0000 1010;1 ==0000 0001
在小端模式 0000 0001 0000 1010,这样就是低存低位,所以a.i = 266
在大端模式 0000 1010 0000 0001 0000 0000… 0000 0000,这样就是低存高位

例题翻转:

#include <stdio.h>
union A
{
	int i;
	char c[2];
}a;
int main()
{
	a.i = 299;
	printf("a.c[0] = %d\n", a.c[0]);
	printf("a.c[1] = %d\n", a.c[1]);
	return 0;
}

分析:
先已知a.i = 299,也就是256+43,可以清楚的知道,a.c[0] = 43,a.c[1] = 1
在这里插入图片描述

如何判别大小端

#include <stdio.h>

int system_mode()
{
	union SM
	{
		char c;
		int i;
	}sm;
	sm.i = 1;
	return sm.c;
}

int main()
{
	if (1 == system_mode())
	{
		printf("this is 小端 mode\n");
	}
	else
	{
		printf("this is 大端 mode\n");
	}
	
	return 0;
}

特殊情况:

int system_mode()
{
	union A
	{
		int i;
		char c;
	}a;
	a.c = 1;
	printf("%d\n", a.i);
	return a.i;
}

在这里插入图片描述
原因在于:我初始化了小的内存,但是我无法保证 int 里面的其余3个字节都是空的。导致出现得出的结果不是1而出现是大端系统的原因,所以最好初始化大的内存 = 1。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值