zoukankan      html  css  js  c++  java
  • C语言笔记(七):字符串、结构体和共用体

    字符串char str []=“helloworld”;

    在c语言里是有字符串类型的。但是实际上,在c里,字符串是将char数组里的内容进行拼接然后在后面加上这个转移字符。表示该char数组的是一个字符串。当然,字符串也是用的双引号。表示null,空的意思,在char里也就说有个空格的位置的字符数组是字符串。

    简单的理解:字符串就是字符数组中的元素拼接然后末尾有个字符

    字符串用%s来接收。即使string的首字母s。

    字符串用%s来接收。即使string的首字母s。

    字符串用%s来接收。即使string的首字母s。

    如果c里没有字符串类型。干嘛用个%s来接收字符串的数据

    定义一个字符串

    不要求全部掌握,但是要知道最简单的定义字符串的方式以及认识这个是一个字符串

    方式一

    #include <stdio.h>
     
    int main ()
    {
       char greeting[6] = {'H', 'e', 'l', 'l', 'o', ''};
     
       printf("Greeting message: %s
    ", greeting );
     
       return 0;
    }
    
    1. 声明并定义了一个char数组greeting。里面的元素hello。
    2. 打印的时候用%s接收,后面直接数组名字就可以了。因为有的原因,这里直接就识别为字符串,如果没有,则这个char数组就是一个char数组。如果还是用%s来接收一个char数组,则会乱码

    方式二(简单)

    最简单的。先说一下printf函数吧,比如要输出一个我爱你这3个字。代码是这样的

    printf("我爱你
    ");
    
    • 是换行的转义字符
    • 在这里然后所有的字符串都是用的双引号

    可以知道,我们也可以直接用双引号的方式来定义一个字符串。

    #include <stdio.h>
     
    int main ()
    {
    	// char love []   ="我爱你;
       char love []   ="我爱你";
    
       printf("Greeting message: %s
    ", love );
     
       return 0;
    }
    

    这样定义一个字符串也是可以。这样就和数组区分开了吧,但是注意,这里默认后面也是有个的,不写其实也是有的,所有的字符串后面默认都有一个当然,你写了也不会报错的

    当然你也可以定义好字符串的长度,比如是char love [10] ="我爱你";

    用方式一的时候,是在数组里放的是单引号要加逗号,也就是{'H', 'e', 'l', 'l', 'o', ''};这里要注意,这种是单引号,每个元素是字符,最后面必须添加‘’

    如果是方式二也可以直接用{“”}的放方式例如: char love [10] = {"我爱你"};但是这个一般都是把{}去掉了的,这种情况是用的双引号,则是字符串,默认会添加的,所以可以不用自己添加

    单引号是字符,双引号是字符串

    单引号是字符,双引号是字符串

    单引号是字符,双引号是字符串

    常用的字符串函数

    c里也有专门用来操作字符串的函数,这些函数在string.h库里,写法和stdio.h一样

    序号 函数 & 目的
    1 strcpy(s1, s2); 复制字符串 s2 到字符串 s1。
    2 strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。
    3 strlen(s1); 返回字符串 s1 的长度。
    4 strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
    5 strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
    6 strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

    大多数string.h库里对字符串进行操作的函数都是str前缀的。所以和这个str记住就是了。当然这些函数不用强行记忆,知道就行了,用多了就知道了。

    代码:

    #include <stdio.h>
    #include <string.h>
     
    int main ()
    {
       char str1[12] = "Hello";
       char str2[12] = "World";
       char str3[12];
       int  len ;
     
       /* 复制 str1 到 str3 */
       strcpy(str3, str1);
       printf("strcpy( str3, str1) :  %s
    ", str3 );
     
       /* 连接 str1 和 str2 */
       strcat( str1, str2);
       printf("strcat( str1, str2):   %s
    ", str1 );
     
       /* 连接后,str1 的总长度 */
       len = strlen(str1);
       printf("strlen(str1) :  %d
    ", len );
     
       return 0;
    }
    

    strlen 与 sizeof的区别

    • strlen 是函数,sizeof 是运算操作符,二者得到的结果类型为 size_t,即 unsigned int 类型。
    • sizeof 计算的是变量的大小,不受字符 影响;而 strlen 计算的是字符串的长度,以 作为长度判定依据。也就说在sizeof的时候也是占有一个未知的 。但是在strlen是不会占的,因为strlen在遇到第一个的时候就结束计算了。

    所以说,在一个字符串中,可以有多个字符的

    输出字符串

    字符的方式输出

    这里也简单介绍几种字符串输出的方式。因为字符串其实就是char数组,则是可以使用循环遍历输出的,这种遍历的方式是用来将字符串用字符的方式输出,也就是将字符串单个单个的拆成字符。当然两种字符串的写法都能用的,因为单引号的方式和双引号的方式都是表示的字符串

    #include <stdio.h>
    #include <string.h>
     
    int main ()
    {
       char str1[12] = "Hello";
       char str2[12] = "World";
    
       int i ;
     
       for(i=0;i<sizeof(str2);i++){
       
    	   printf("
    %c
    ",str2[i]);
       }
     
       return 0;
    }
    

    这里使用的for循环,字符串也是特殊的字符数组,所以下标也是从0开始的。而且这里用的sizeof()来计算的字符串的长度,所以是直接<这个长度就ok。然后依次打印相应索引的字符。

    如果使用的是strlen()则是<=,至于为啥有个=,因为strln()=sizeof()-1

    这里注意,因为定义的字符串数组长度是12但是实际上只用到了5个长度的字符串,因为单个字符占一个位置嘛。还剩下6个位置,则会打印6个?(问号),为啥不是(12-5=7)7个,因为/0是必须占用一个位置的,所以字符串的字符能用实际上是规定的长度-1也就是(12-1=11)个

    直接打印字符串

    如果是直接输出字符串。因为有时候需要用到。

    这里也有两种方式,

    1. 一种就是直接%s接收,的方式

      #include <stdio.h>
      #include <string.h>
       
      int main ()
      {
         char str2[12] = "World";
      
         printf("%s
      ",str2);
       
         return 0;
      }
      
    2. 还有一种是直接打印输出。

      #include <stdio.h>
      #include <string.h>
       
      int main ()
      {
         char str2[12] = "World";
      
         printf(str2);
       
         return 0;
      }
      

      很明显这种是无法直接换行的,但是方便

    结构体struct

    其实就是数组的一种扩展类型,因为数组只能存储同一种数据类型。所有结构体就来了。结构体是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据这个可以说有点像对象。有各种属性,比如2个小狗,有年龄、性别、毛色等等属性。但是年龄和性别又不是同一种类型。所以如果要使用就得创建两个数组来存储两种不同类型的属性(变量)

    这里注意,同一个结构体类型的变量,属性一致

    这里注意,同一个结构体类型的变量,属性一致

    这里注意,同一个结构体类型的变量,属性一致

    比如都是人类,张三和李四都有眼睛鼻子耳朵;

    比如下面方式一的dog01和dog02,都是一个类型的,所以他们的属性都一致。

    定义结构体

    一般结构体是定义在函数外面的

    必须使用struct 关键字

    语法 struct 结构体类型名字(结构体标签)

    {

    属性1;

    属性2;

    ...

    }结构体变量名;(不要忘记这个分号

    是不是很像枚举啊枚举是用的enum关键字,而结构体是struct关键字

    所以定义的几种方式也和枚举是类似的。在定义一个结构体的时候,首先要有struct关键字。然后可以只出现结构体标签和属性,也可以是出现属性和结构体变量名

    • 不能结构体标签和结构体变量名,不要属性例如struct student{};
    • 不能结构体标签和结构体变量名,不要属性例如struct student{};
    • 不能结构体标签和结构体变量名,不要属性例如struct student{};

    简单的说 结构体标签、属性、结构体变量名两两出现

    结构体可以定义在函数里,则及时局部结构体,也可以定义在外面作为全局变量使用。

    方式一

    定义的时候定义了结构体类型和结构体变量

    这里的Dogs放在mian函数里的,也可以放在main函数外 ,但是这个不影响结构体类型,重要的而是结构体变量也就是dog01和dog02。如果dog01和dog02是在函数里,则是局部变量。在函数外面,则是全局,这里在变量的时候说过了。所以这里就不要纠结类型是啥全局和局部了。类型都是存储在内存的

    看代码吧:

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}dog01,dog02;//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
       return 0;
    }
    
    

    方式二

    定义的时候只定义了结构体类型名字

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	};
        struct Dogs dog1;
        struct Dogs dog2;
        struct Dogs dog3,dog4;
       return 0;
    }
    
    

    可以知道,这里创建了4个结构体变量。这个和基本类型创建变量的时候类似。但是这里的结构体类型是自己定义的。所以需要加上struct关键字;

    方式三

    直接创建结构体变量

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	} dog1;
       return 0;
    }
    

    这里没后声明结构体类型也就是说,不晓得是啥类型的结构体,所以这种方式和下面也就是方式一是不一样的。虽然属性一样,但是类型不一样,这里是个坑

    //定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}dog01,dog02;//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
    

    方式四

    使用typedef,这个typedef是啥,后面再说吧,你知道这个typedef能自定义类型就OK了。

    #include <stdio.h>
    int main ()
    {
    
    	typedef struct {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}Dogs;	//定义了小狗类型的结构体这里是定义在函数里面的
      	 Dogs dog1;
         Dogs dog2;
         Dogs dog3,dog4;
       return 0;
    }
    

    好滴,看看上面的代码,可以知道。typedef就是用来创建的一个struct类型的,类型名也就是之前我们放变量名的位置。所以说这种方式是直接自定义了一个类型。

    且使用的时候和基本类型完全一致,直接类型名+变量名;

    结构体不完全声明

    不完全声明,有点难理解,但是这种情况下,是两个结构体互相包含的情况,比如有两个小狗类型,一个是哈士奇,一个是泰迪,虽然都是狗,但是是两种类型的狗。而且哈士奇有泰迪里的某些属性,比如说年龄。而泰迪里也有哈士奇里的某些属性,比如说毛发。

    struct Taidi;
    struct Hashiqi{
    
        struct Taidi *age;
    
    };
    struct Taidi{
     
        struct Hashiqi *maofa;
    };
    
    

    则这里就需要先对泰迪进行不完全声明。这个声明也就是和声明变量类似,这里是关键字加类型名

    也就说结构图互相使用对方的属性,当然为啥要声明泰迪而不声明哈士奇。虽然都说两者之一都可以。但是我认为是哈士奇先用的泰迪的属性,泰迪是在哈士奇后面才会定义属性,所以需要先声明泰迪,告诉系统,我这里有个泰迪,然后哈士奇就可以找到泰迪的属性咯

    结构体变量的初始化

    如果一个结构体有3个属性,只初始化了一个属性,其他两个则是相应类型的默认值。如果都不初始化,则内存会随机分配,则是乱码,不能直接{}啥都不赋值。这个是代表的是语法体。必须要有内容

    不能再结构体属性里直接初始化

    不能再结构体属性里直接初始化

    不能再结构体属性里直接初始化

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age=12;
    		char  color [20]="白色";
    	}dog01,dog02;//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
      	printf("age:%d
     color:%s
    ",dog01.age,dog01.color);
        return 0;
    }
    

    顺序初始化(用这个)

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}dog01={12,"白色"},dog02={22,"黑色"};//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
        struct Dogs dog03 = {23,"灰色"};
    	printf("小狗1 age:%d	color:%s
    ",dog01.age,dog01.color);
    	printf("小狗2 age:%d	color:%s
    ",dog02.age,dog02.color);
        printf("小狗3 age:%d	color:%s
    ",dog03.age,dog03.color);
       return 0;
    }
    
    
    • 在结构体变量的位置,直接用{}按照结构体属性的位置进行初始化
    • 这种方式在定义结构体的时候直接给变量赋值也是可以的

    这里get一下,属性的char定义的是一个数组,初始化的时候是给的一个字符串。则数组就变成字符串咯

    乱序初始化

    我在vc里识别不了.和:应该这个是c++里的语法,所以还是使用顺序的吧

    #include <stdio.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	};
        //方式一
        struct Dogs dog01={
    		.age=12,
    		.color="白色",
    	};
       	struct Dogs  dog02={
    		.color="黑色",
    		.age=22,
    	};
        //方式二
        /*
            struct Dogs dog01={
    		age:12,
    		color:"白色",
    	};
       	struct Dogs  dog02={
    		color:"黑色",
    		age:22,
    	};
        
        */
    	printf("小狗1 age:%d	color:%s
    ",dog01.age,dog01.color);
    	printf("小狗2 age:%d	color:%s
    ",dog02.age,dog02.color);
       return 0;
    }
    
    

    访问结构体

    之前打印的时候就已经使用了。直接结构体变量.属性。这里字符串也直接.数组名

    使用strcpy来给字符串属性赋初值

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	};
        struct Dogs dog03 = {12};//这里按照顺序,只赋值了age
    	strcpy(dog03.color,"超级黑色");//使用了strcpy。吧逗号后面的内容赋值给逗号前面的内容
        printf("小狗3 age:%d	color:%s
    ",dog03.age,dog03.color);//打印结构体属性
       return 0;
    }
    

    结构体作为函数参数

    #include <stdio.h>
    #include<string.h>
    
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}dog01={12,"白色"},dog02={22,"黑色"};//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
    
    
    //声明打印函数
    int PrintfStruct(struct Dogs test);
    
    
    int main ()
    {
    
    	//给狗3赋值(初始化)
    	//按照顺序,是给age赋值
        struct Dogs dog03 = {23};
    	//用复制函数给color赋值
    	strcpy(dog03.color,"超级黑色");
    	
    	//打印
    	PrintfStruct(dog01);
    	PrintfStruct(dog02);
    	PrintfStruct(dog03);
       return 0;
    }
    
    
    //定义一个打印结构体属性的函数PrintfStruct()传入一个结构体
    //这个test是形式参数,随便命名
    int PrintfStruct(struct Dogs text){
    
    	printf("小狗的属性 age:%d	color:%s
    ",text.age,text.color);
    
    return 0;
    }
    

    指向结构的指针

    声明一个名字是struct_pointer是Dogs类型的指针

    struct Dogs *struct_pointer;
    

    现在,您可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,如下所示

    struct_pointer = &Dogs;
    

    将Dogs的地址赋值给这个struct_pointer

    为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符

    这里还是用打印函数来做例子

    这里打印函数里的参数是一个Dogs类型的指针,所以需要传一个地址,或者传一个指针也是可以的。

    这里直接传入指针变量的地址

    #include <stdio.h>
    #include<string.h>
    
    	//定义了小狗类型的结构体这里是定义在函数里面的
    	struct Dogs {
    		//结构体类型里的属性,则可以通过变量来对结构体属性进行赋值等操作
    		int  age;
    		char  color [20];
    	}dog01={12,"白色"},dog02={22,"黑色"};//在定义结构体的时候就直接定义了结构体变量了。且变量名是dog01和dog02,这里有两个变量
    
    
    //声明打印函数
    int PrintfStruct(struct Dogs *dog);
    
    
    int main ()
    {
    
    	//给狗3赋值(初始化)
    	//按照顺序,是给age赋值
        struct Dogs dog03 = {23};
    	//用复制函数给color赋值
    	strcpy(dog03.color,"超级黑色");
        
    	//声明三个指针,用来放dog123的地址
      struct Dogs *dog1=&dog01;
      struct Dogs *dog3=&dog03;
      struct Dogs *dog2=&dog02;
    	//打印
    	PrintfStruct(&dog01);
    	PrintfStruct(&dog02);
    	PrintfStruct(&dog03);
       return 0;
    }
    
    
    //定义一个打印结构体属性的函数PrintfStruct()传入一个结构体
    //这个test是形式参数,随便命名
    int PrintfStruct(struct Dogs *dog){
    
    	printf("小狗的属性 age:%d	color:%s
    ",dog->age,dog->color);
    
    return 0;
    }
    

    共用体union

    共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。这里要知道共用体是在内存里用用的同一块内存空间就是了

    定义共用体

    这里使用的关键字就是union,方式与定义结构类似。union 语句定义了一个新的数据类型,带有多个成员

    union Data
    {
       int i;
       float f;
       char  str[20];
    } data;
    
    1. Data:共用体类名
    2. data:共用体变量名
    3. {}里面的内容是共用体属性
    4. 末尾记得有个分号

    和结构体定义和声明以及调用的方式一样。只是所有的属性都是存放在一个内存空间里的。当然这里有三种数据类型,则会选择最大的数据类型所占的内存空间来放所有的数据类型。

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
       printf( "data占用的字节 : %d
    ", sizeof(data));
     
       return 0;
    }
    

    访问共用体成员

    和结构的访问方式一样。都是通过打.调用

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
       data.i = 10;
       data.f = 220.5;
       strcpy( data.str, "C Programming");
     
       printf("data占用的内存空间:%d
    ",sizeof(data));
    
       printf( "data.i : %d
    ", data.i);
       printf( "data.f : %f
    ", data.f);
       printf( "data.str : %s
    ", data.str);
     
       return 0;
    }
    

    在这里,我们可以看到共用体的 if 成员的值有损坏,因为最后赋给变量的值占用了内存位置,这也是 str 成员能够完好输出的原因。这是在赋值的时候,i和f以及字符串是共同使用的一块内存空间,当然这里是使用的最大的空间则是str的空间,但是优先存储的是最后赋值的值,则是先放的字符串,然后再是i和f的,但是在存储i和f的时候由于空间不够,因为只能放20字节,所有就有内存丢失了

    通过sizeof函数,也能看出data是占用的20个字节的内存空间

    如果想要输出完整内容,则需要一个一个的存储。

    #include <stdio.h>
    #include <string.h>
     
    union Data
    {
       int i;
       float f;
       char  str[20];
    };
     
    int main( )
    {
       union Data data;        
     
      printf("data占用的内存空间:%d
    ",sizeof(  data));
    
        
       data.i = 10;
    	printf( "data.i : %d
    ", data.i);
    	
       data.f = 220.5;
          printf("data占用的内存空间:%d
    ",sizeof(  data.f));
    
        //装了f后,在打印i
       printf( "data.f : %f
    ", data.f);
       printf( "data.i : %d
    ", data.i);
    
    
    
       strcpy( data.str, "C Programming");
       printf( "data.str : %s
    ", data.str);
       //装了字符串后,在打印i,f
       printf( "data.i : %d
    ", data.i);
       printf( "data.f : %f
    ", data.f);
       return 0;
    }
    

    这里为啥能打印完好的内容呢?首先要知道,这是一个共用体,则data的内存空间就是最大的变量的则是20字节,这个20字节是定死了的。

    从上面的结果可以知道,当创建了f后,打印i还是乱码。虽然f占用4个字节,i占用4个字节,但是当他们在一个内存空间里存储的时候,就会让计算机不知道怎么换算了。因为二进制的01混淆了。所有结果就有错误,当然最后一个存储的数据是不会有错误的,只会让之前存储的数据错误

    所以在存储字符串后,打印i,f还是会有错误,但是在存储了i然后马上打印,然后再存储f后马上打印,则不会出错,因为每次打印但是时候都是将该变量作为的最后一个存储的数据;

    结构体与共用体的差别

    • 结构体变量所占内存长度是其中最大字段大小的整数倍
    • 共用体变量所占的内存长度等于最长的成员变量的长度。

    结构体变量内存长度

    所有的长度都是说的 字节

    首先先看结构体变量中占用最大的字节,然后将这个最大的字节作为标准,也就说,结构体的内存是这个最大的字节的整数倍,如果其他变量加起来不够这个最大字节的整数倍,则进行自动添加到这个字节的整数倍就ok,看下面的例子

    struct {   char a;   short b;   char c; }S1;
    
    1. 最大的是short,占用2个字节。好滴然后就将2作为一个标准
    2. 这里要知道char是占1个字节的。short是占用2个字节的。
    3. 所以short就不做添加内存的操作依旧保持2个字节
    4. 但是第一个char只有1个字节,所以需要添加1个,才能到2
    5. 第二个同理。所以就是2+2+2=6个字节
    struct {  char  a;  char  b;  short c; }S2;
    
    1. 最大的是short,占用2个字节。好滴然后就将2作为一个标准
    2. 这里要知道char是占1个字节的。short是占用2个字节的。
    3. 所以short就不做添加内存的操作依旧保持2个字节。然后看其他的
    4. 这里的第一个char和第二个char都各自占用1个字节,所以他们凑一对,就是2个字节了
    5. 则就是2+2=4

    如果是结构体里有其他结构体类型的数据呢

    typedef struct A
    {
        char a1;
        short int a2;
        int a3;
        double d;
    };
    
    A=16
    
    typedef struct B
    {
        long int b2;
        short int b1;
        A a;
    };
    

    上面的B中有A类型的数据。

    1. 不看A类型的。先看B类型的变量。(long int占用4个字节,shout int占用2个字节)
    2. 最大的是4,则用4作为标准
    3. long int刚好,所以不看。直接记做4
    4. shourt int 差2个,所以补上2,
    5. 则就是4+4=8
    6. 然后看A
    7. A里面最大的是double 也就是最大的是8,所以将8做为标准
    8. 直接忽略最大子double,记做8
    9. 然后看其他的,double前面的直接相加1+2+4=7还是不够,在加1
    10. 所以8+8=16
    11. 最终的就是8+16=24字节

    总结

    1. 直接找属性里最大的字节,将该字节作为标准。然后看该字节前后的字节能否加起来等于该字节,如果小于,则添加相应的数凑成该字节数。

    2. 如果有多个该最大字节的。将他们抛开不看,记做最大的数,然后分别看前后,直接凑。

      #include <stdio.h>
      #include <string.h>
       
      int main( )
      {
      typedef struct A
      {
          char a1;
          short int a2;
          double c;
          int a3;
          double d;
      } a;
      
      printf("结构体A的占用字节数是:%d
      ",sizeof(a));
         return 0;
      }
      

      比如这里,有两个double所以直接先记下8+8=16.然后看double的前后,第一个double前面1+2=3不够所以要凑5=8,

      第二个double前面也不够,所以加4个则是4+4=8;所以最终是16+8+8=32

    共用体的内存长度

    最大属性的内存长度

  • 相关阅读:
    201671010113 201620172 《JAVA程序设计》第三周
    201671010113 201620172 《JAVA程序设计》浅入JAVA
    201671010113 201620172 《JAVA程序设计》第四周
    C++中的四种类型转换符
    《统计学习方法》 梯度下降的两种应用场景
    【转载】推荐系统算法总结
    剑指offer面试题1
    SQL清空数据技巧
    DataGridView绑定List时无法进行添加删除操作的解决方法
    MyEclipse新建web project和navicat110_mysql_en工具
  • 原文地址:https://www.cnblogs.com/yuxiangqiezi/p/13128603.html
Copyright © 2011-2022 走看看