黑马程序员——C语言笔记之结构体以及枚举

------- android培训java培训iOS培训.Net培训、期待与您交流! ----------

虽然结构体的用法很简单,但是OC里面用的频率很高,所以也是一个跟指针一样重要的知识点。

C语言构造类型:

       由一个或者多个已定义类型的元素用构造的方法,构造新的类型

构造类型有三种:

       数组类型   结构体类型   共用体(联合)类型

其中,结构体:

       是由一个或者多个相同或者不同的数据类型组成的构造类型

一、结构体

1、定义:

       struct 结构体名{


           成员列表;

 

       }; //注意此处的分号不能省

//定义一个iPhone的结构体
      struct iPhone{
 
          char *color;
          float  screenSize;
          int  sn;
          int  imei;
 
      };

2、结构体变量及定义方法

1)先定义结构,再说明结构变量

struct stu{
     int num;
     char name[20]; 
     char sex;
     float score; 
};
struct stu boy1,boy2;
2)在定义结构类型的同时说明结构变量

struct stu{
     int num;
     char name[20];
     char sex;
     float score;
}boy1,boy2;

3)匿名结构体定义结构变量

struct{
     int num;
     char name[20];
     char sex;
     float score; 
}boy1,boy2;
注意:定义结构体完成后,并不会给结构体分配存储空间,定义结构体变量后才分配空间。

结构体变量中成员的访问方法:

   结构体变量名.成员名

如果成员也是一个结构体,则:

  结构体变量名.成员名.成员名...

3、结构体变量的初始化

1)先定义结构体变量,然后再初始化

struct stu boy1,boy2; 
boy1.num = 1010; 
strcpy(boy1.name, "bbbbb");
//boy1.name="cjk"; //这是错误的,相当于char name[20], name="abc"; 如果写成char *name, 则name="abc"可以;
boy1.sex = 'f';
boy1.score = 18.0f;

2)定义的同时初始化

(1)全部初始化

//方法1:
struct stu{
     int num;
     char name[20];
     char sex;
     float score;
} av1={1012,"zhangsan",'f',30};
//注意 "xzmly"初始化赋值给了name[20];
//方法2:
struct stu boy1={1011,"lisi",'f',23};
//注意:初始化的顺序必须与结构体定义的时候成员的顺序一致
 

<pre name="code" class="plain">//使用另外一已经存在的结构体初始化新的结构体//两个相同类型的结构体变量的赋值,相当普通变量的赋值,是整体拷贝,而不是地址赋值,例:
struct Student stu1 = {"wangwu",12,'f'};
struct Student stu2;stu2 = stu1; // 这相当于把stu1里面所有的成员元素赋值给了stu2

(2)部分初始化

structstuboy1={.name="highge"}; //只给name单独赋值{}不能少

4、结构体变量存储原理

结构体占用的内存空间是每个成员占用的字节数之和(考虑对齐问题)

计算方法:

1)先找对齐模数

2)再计算结构体变量中各个成员占用的字节和

struct A{
short a;  // 2字节 + 2 下面是4,2不是4的倍数,所以加上2
int b;    // 4字节     上面加起来是8个字节,下面是1,8是1的倍数,所以不加 
char c;   // 1字节 + 7 上面下面是8,上面加起来是9,9不是8的倍数,所以加上7
double d; // 8字节     直接相加是24,24正好是这里面所有数字的倍数,所以就是24
};
struct B{
double d; // 8字节     下面是2,8是2的倍数,所以不加
short a;  // 2字节 + 2 上面加起来是10,下面是4,10不是4的倍数,所以加上2
int b;    // 4字节     上面加起来是12,下面是1,12是1的倍数,所以不加
char c;   // 1字节 + 7 所有的加起来是17,17并不是2 8 4 的倍数,所以要成为所有的倍数需要加上7最后得24
};

二、结构体数组

结构数组的每一个元素都是具有相同结构类型的下标结构变量

1、结构数组的定义:

    struct 结构名{

           成员表列;

}数组名[数组长度];

struct stu{
       int num;
       char *name;
       char sex;
       float score; 
}boy[5];
2、结构数组的初始化

1)定义的同时进行初始化

struct stu s[2]={{12,"sb"},{18,"fengjie"}};

2)先定义,后初始化,整体赋值

s[1]=(struct stu){23,"xiaoluo"}; // (struct stu)不能少

3)先定义,后初始化

s[1].age=12; strcpy(stu[1].name, "xxoo"); 

三、结构体指针

结构体指针变量中的值是所指向的结构体的首地址

1、定义

struct 结构名 *结构指针变量名

2、结构体指针间接访问成员值

         (*结构指针变量).成员名

或为:

         结构指针变量->成员名

四、结构体嵌套

成员又是另一个结构体变量,即构成了嵌套的结构

Struct Date{
    int month;
    int day;
    int year; 
}
struct stu{
    int num;
    char *name;
    char sex;
    struct Date birthday; Float score;// 包含了Date结构体的结构变量
}
注意:结构体不可以嵌套自己的变量,但可以嵌套自己类型的指针

//定义一个全局结构体,作用域到文件末尾 
struct Person{
      int age;
      char *name;
      struct Person *son;
};
struct Person son = {4,"kim"}; 
struct Person p = {30,"lzy",&son};
printf("name = %s,son name = %s\n",p.name,p.son->name);
五、结构体指针作为函数的参数

void changeTime(struct Time *time); 
struct Time t;
changeTime(&t);


六、枚举类型

枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解成为任何基本类型

1、定义

enum 枚举类型名{枚举值表};

2、枚举变量的定义和使用

1)先定义类型,后定义变量

enum weekday{sun,mou,tue,wed,thu,fri,sat};
enum weekday a,b,c;
2)同时定义变量和类型

enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c; 
enum { sun,mou,tue,wed,thu,fri,sat }a,b,c;//匿名定义

关于枚举类型的代码段

#include <stdio.h>
//默认值              0            1            2
//手动赋值            5            6            7
enum iColor{kIcolorWhite=5,kIcolorBlack,kIcolorTHJ};

int main(int argc, const char * argv[]) {
    
    //1、枚举类型变量的定义
    enum iColor  iPhoneColor;  //iPhoneColor的取值是有要求的
    //取值应为kIcolorWhite,kIcolorBlack,kIcolorTHJ中的其中一个
    
    enum Sex{kSexMan,kSexWomen,kSexYao} isex;
    
    //2、枚举类型变量的初始化
    
    //给枚举变量赋值
    iPhoneColor = kIcolorTHJ;
    isex = kSexYao;
    
    //3、枚举变量如何使用
    printf("%d\n",iPhoneColor);
    
    //4、枚举变量的值
    //枚举类型定义完成以后,系统会自动给枚举的每个元素都会赋值一个整形的初值
    // 默认初值:从第一个元素开始值为0,以后个元素的值,是上一个元素的值+1,
    
    //5、应用
    struct Person{
    
        char *name;
        //char sex; //'z'
        enum Sex isex; //kSexMan,kSexWomen,kSexYao
    };
    
    //6、不按套路的出牌
    iPhoneColor = 3.4;  //尽量不要这么干
    printf("%d\n",iPhoneColor);

    return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: memset 函数可以用来将一块内存空间的值设置为指定的值,它常用于对数组、结构等数据结构进行初始化操作。不过需要注意的是,对于结构内部的指针变量,使用 memset 并不能直接将其初始化为 NULL,因为在内存中 NULL 的值并不是 0。 一个比较好的做法是,在结构定义的时候将指针变量初始化为 NULL,例如: ``` struct Node { int data; struct Node *next; }; struct Node node = {0, NULL}; ``` 这样就可以确保在使用 memset 进行清零操作时,结构内部的指针变量也被正确地初始化为 NULL。 如果要使用 memset 对结构进行清零操作,可以使用以下代码: ``` struct Node node; memset(&node, 0, sizeof(struct Node)); ``` 这里我们使用 & 符号获取结构变量的地址,然后将其作为 memset 函数的第一个参数传入。第二个参数是要设置的值,这里我们设置为 0 表示清零。第三个参数则是结构的大小,可以使用 sizeof 运算符来获取。 需要注意的是,使用 memset 函数进行清零操作时,要确保结构中的所有成员变量都可以被正确地清零,否则可能会导致程序出现未知的错误。另外,在使用 memset 函数时,也需要注意不要越界访问内存空间。 ### 回答2: memset函数是C语言中用于对指定的内存块进行初始化的函数,常见的使用方式是对数组和字符串进行初始化。然而,对于结构内部包含指针的情况,memset函数并不能直接用于初始化指针所指向的内存空间。 原因在于,memset函数是以字节为单位进行操作的,而指针的大小往往是4个字节或8个字节,因此无法准确地将指针的值初始化为NULL或其他指定的值。 对于结构内部的指针,我们可以通过手动逐个成员初始化的方式,来达到初始化的目的。例如,可以先将结构的指针成员赋值为NULL,然后再逐个成员进行初始化。示例如下: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int *ptr; int num; } MyStruct; void initializeStruct(MyStruct *s) { s->ptr = NULL; s->num = 0; } int main() { MyStruct s; initializeStruct(&s); printf("ptr = %p\n", s.ptr); printf("num = %d\n", s.num); return 0; } ``` 在上述代码中,通过initializeStruct函数对结构s进行初始化,将s.ptr赋值为NULL,将s.num赋值为0。这样就可以实现对结构内部指针的初始化。 需要注意的是,对于结构内部嵌套的其他结构或者动态分配的内存空间,我们同样需要手动进行逐个成员初始化,以确保结构内部的所有指针都被正确初始化,并且不产生内存泄漏的问题。 ### 回答3: memset是C语言中的一个函数,用于对一段内存空间进行初始化操作。它可以将指定内存区域的每个字节都设置为特定的值。 在C语言中,结构是一种用户定义的数据类型,它可以包含多个不同类型的变量。结构可以被看作是一种形式上的数据集合,可以统一管理一组相关的变量。 结构内可以包含指针变量,这些指针变量可以指向堆内存中的某个地址。然而,当我们使用memset来初始化结构内的指针时,需要注意指针变量指向的内存空间是否已经被分配。 由于memset函数只能设置内存空间的值,并不能为指针变量分配内存,因此在使用memset初始化结构内指针之前,需要先为指针变量分配足够的内存空间。否则,如果指针未指向有效的内存地址,当我们尝试访问这个指针时,可能会导致程序崩溃或者产生未知的结果。 所以在使用memset来初始化结构内指针时,我们需要先为这些指针变量分配内存,并在memset函数调用之后再对这些指针进行进一步的操作,以确保指针变量的正确性和有效性。 在使用结构时,我们也可以将多个结构通过指针链接成链表结构,形成一种更加复杂的数据结构。链表可以通过指针将各个结构连接起来,方便进行数据的插入、删除和查找等操作。 此外,C语言还提供了枚类型,它可以定义一些常量集合,方便程序员使用和维护。枚类型可以用于表示一组相关的取值,通过定义的枚常量,我们可以直观地理解程序中的某些状态或者选项。 总之,结构、链表和枚是C语言中重要的概念和特性,它们能够帮助我们更好地组织和管理程序中的数据,提高代码的可读性和可维护性。在使用这些特性时,我们需要注意指针的正确使用和内存的分配释放,以避免出现错误和内存泄漏等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值