结构体:
定义:在c语言中为数据类型的集合,不是变量类型。写在主函数外面。
struct+结构体名称
{
}变量名表列;
实例程序:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
struct student//定义结构体名称
{
char name[20];
int age;
char sex;
int id;
};
int main()
{
int i;
struct student * stu[5];//定义结构体属性的指针数组
printf("please input:\n");
for(i=0;i<5;i++)
{
stu[i]=(struct student*)malloc(sizeof(struct student)*50);//给指针数组每个元素分配堆空间
scanf("%s%d %c %d",stu[i]->name,&stu[i]->age,&stu[i]->sex,&stu[i]->id);//分别对应结构体成员的数据类型,输出%s %d等
值得注意的是结果体成员是int char修饰的值,在scanf里面依旧要加&取地址。数组成员就不需要。
}
printf("*********************\n");
for(i=0;i<5;i++)
{
printf("%s %d %c %d\n",stu[i]->name, stu[i]-> age , stu[i]->sex , stu[i]->id);
//i是指针数组的下标,指针数组存放着每个指向结构体数据指针的地址。
}
}
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
struct dd
{
char a;
int b;
};
结构体长度计算:
规则:结构体长度:一定是最长成员的整数倍(除了double)
:每个成员的偏移量:一定是该成员长度的整数倍
题目1:
计算下列结构体的长度
struct student
{
int a;
char b;
};
答案为8,因为int占用4个字节而b只用1个字节,共5个字节,不是4的倍数所以加3 ;同样
struct student
{
int a;
char b;
};也为8
偏移量:
题目2:
struct student
{
short name[20];//数组按照20个short类型变量计算
// int age;
char sex;
char a;
// int e;
// long rr;
struct dd s;
} ;
int main()
{
/* struct student si={"aaa",10,'o'};
struct student*s3=(struct student*)malloc(sizeof(struct student));//定义结构类型的指针分配空间
printf("%s %d %c\n",si.name,si.age,si.sex);
scanf("%s%d %c",si.name,&si.age,&si.sex);
printf("%s %d %c\n",si.name,si.age,si.sex);
strcpy(s3->name,"aaa");//指针结构体成员->
s3->age=10;
s3->sex='m';
printf("%s%d%c\n",s3->name,s3->age,s3->sex);*/
printf("%d\n",sizeof(struct student));
}
关于偏移量,内存中往里面输入新的类型数据时,前面的字节数一定这个类型的整数倍
#include <stdio.h>
struct stu
{
short b;
char t;
};
struct student
{
int a;
char b;
int c;
char str[13];
struct stu d ;//先按顺序计算int a和char b大小占用8个字节在计算int c占用12个字节,最后计算数组占用25个字节,单独计算stu的字节大小为3个字节,25不是3个的倍数,所以加1为26加上结构体stu本身共29个字节。最后计算总长度时按最长成员int计算,
29不是4的倍数加上3变成32为4的倍数,所以最终结果为32.
};
int main()
{
printf("%d\n",sizeof(struct student));
}
结构体数组:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{
char name[20];
int age;
char sex;
int id;
};
int main()
{
int i;
struct student * stu[5];//定义带有结构体数组属性的指针数组
printf("please input:\n");
for(i=0;i<5;i++)
{
stu[i]=(struct student*)malloc(sizeof(struct student)*50);//给指针数组每个元素指针分配空间
scanf("%s%d %c %d",stu[i]->name,&stu[i]->age,&stu[i]->sex,&stu[i]->id);//依次按元素下标引用结构体成员,由于是通过数组元素引用结构体成员,而元素为指针,所以要加->。
值得注意的是:结构引用格式:stu[i]->name和stu[i]->age,侧重点都在后面,也就是真正决定这个变量数据类型是name和age。
因为name是个数组不需要加&,而age是个int需要加&地址
}
printf("*********************\n");
for(i=0;i<5;i++)
{
printf("%s %d %c %d\n",stu[i]->name, stu[i]-> age , stu[i]->sex , stu[i]->id);
}
}
内存管理:
c语言中指的内存都是虚拟内存
存储形式为:
1G 内核态
数据段 :全局变量,static静态变量分为bss和数据段
代码段:代码,常量(只读)
栈:局部变量(形参)
堆空间:malloc free
堆和栈区别:
栈:操作系统管理,申请释放都是操作系统完成的;
堆;用户管理,申请和释放由用户完成malloc释放free
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int global=0;//数据段
char*p1;//数据段
int main()
{
int a;
char s[]="abcd";//定义在栈上面(*s++)是可以的s++不可以
char*p2;//
char*p3="1234566";
static int c=0;
p1=(char*)malloc(100);
strcpy(p1,"123456789");
return 0;
(*s)++;
s++;
p3++;
(*p3)++;
}
注意的是*p++,是*p取值在地址加1;
联合体 union test
{
char a;
int b;
long c;
}所有成员共用一段内存。只为最长的成员分配空间:
#include <stdio.h>
union test
{
int a;
int b;
long c;
};
int main()
{
union test i;
i.a=0;
printf("%d %d\n",i.a,i.b);
printf("%d\n",sizeof(union test));
return 0;
}
运行结果:
[root@localhost jiegouti]# ./union
0 0
4
因为是同一块内存,所以给a赋值等于给b赋值。
大端小端:
大端:高字节放低地址,低字节放高地址
小端:低字节放高地址,高字节放低地址
a=0x102
0000 0001 0000 0010
高字节 低字节
b[0]=1;大端
b[0]=2;小端
#include <stdio.h>
union test
{
int a;
char array[2];
};
int main()
{
union test t;
t.a=0x0102;//占用同一内存
if(t.array[0]==1 && t.array[1]==2)
{
printf("big\n");
}
else if(t.array[0]==2&& t.array[1]==1)
{
printf("little\n");
}
return 0;
}
将大端变成小端的方法:
#include <stdio.h>
int main()
{
int a=1;
int result;
result=((a&0x000000ff)<<24)|
((a&0x0000ff00)<<8)|
((a&0x00ff0000)>>8)|
((a&0xff0000)>>24);
printf("%d\n",result);
return 0;
}