复习结构体

结构体:

定义:在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;
  

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值