(一)结构体类型

1.简介:

例:

struct date

{

  int month;

  int day;

  int year;

};

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 类型*/

  char addr[30];

}student1,student2;

(1):结构体可嵌套

(2):与枚举相比结构体内元素为变量,而枚举为常量

(3):元素只能单个引用:如:student.num;  student.birthday.month;

(4):内部元素变量可以与其他变量重名且互不影响;

(5):赋值:student.num = 10010;

2.初始化

(可直接赋值)

struct student

{

  long int num;

  char name[20];

  char sex;

  char addr[20];

}a = {10101,"Li Lin","M","BeiJing Road"};

3.结构体数组

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 类型*/

  char addr[30];

};

struct student stu[3];

注:数组中每一个元素都是一个结构体类型数据;

4.指向结构体类型数据的指针

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 类型*/

  char addr[30];

};

struct student stu_1;

struct student *p;

p = &stu_1;

注:

(1)一个结构体变量的指针就是该变量所占据的内存段的起始地址(开头地址);

(2)(*p).num 等价于 stu_1.num;(*p两端的括号不能省略)

(3)(*p).num 等价于 p->num; (-> 称为指向运算符)

(4)如下运算

p->n; 得到p指向的结构体变量中的成员n的值。

p->n ++;得到p指向的结构体变量中的成员n的值,用完该值后使它加1。

++ p->n;得到p指向的结构体变量中的成员n的值加1,然后再使用它。

-> 运算优先级大于 ++;

5.指向结构体数组元素的指针

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 类型*/

  char addr[30];

};

struct student stu[3];

struct student *p;

for( p = stu;p < stu + 3;p ++)

  printf( "%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);

注:p是一个指向struct student 类型数据的指针变量,它用来指向一个struct student 类型的数据(及:stu数组的一个元素如stu[0],stu[1],的起始地址),不应用来指向stu数组元素中的某一成员,

p = stu[1].name;   这样的用法是错误的

但是:

强制类型转换后可以用

p = (struct student *)stu[0].name;  这样是正确的;

这样的话:p的值是stu[0]元素的name成员的起始地址。printf(“%s”,p)输出stu[0]中成员name的值。但printf(“%s”,p +1)则输出 stu[1]中name的值。p+1 的值是在p值的基础上加上结构体struct student的字节长度。

因为:p加减运算他的类型就是他的最小运算单元
  

6.结构体变量做函数参数

注:用结构体变量做函数参数时,采用值传递的方式,将结构体变量所占的内存单元的内容全部顺序传递给形参。

#include<stdio.h>

#include<string.h>

#define FORMAT "%d\n%s\n%f\n%f\n%d\n"

struct student

{

  int num;

  char name[20];

  float score[3];

} ;

void main()

{

  void print(struct student);

  struct student stu;

  stu.num = 12345;

  strcpy(stu.name,"Li Li");

  stu.score[0] = 67.5;

  stu.score[1] = 89;

  stu.score[2] = 78.6;

  print(stu);

}

void print(struct student stu)

{

  printf(FORMAT,stu.num,stu.name,stu.score[0], stu.score[1],stu.score[2]);

  printf("\n");

}

运行结果:

12345

Li Li

67.500000

89.000000

78.599998

 7.用指针处理链表

例:

#include<stdio.h>

#define NULL 0

struct student

{

  long num;

  float score;

  struct student *next;

};

void main()

{

  struct student a,b,c,*head,*p;

  a.num = 10101;a.score = 89.5;

  b.num = 10103;b.score = 90;

  c.num = 10107;c.score = 85;

  head = &a;

  a.next = &b;

  b.next = &c;

  c.next = NULL;

  p = head;

  do

  {

    printf("%ld%5.1f\n",p -> num,p -> score);

    p = p -> next;    //使P指向下一结点

  }

  while(p != NULL);

}

运行结果:

10101  89.5

10103  90.0

10107  85.0

注:

该例子结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为“静态链表”。

8.处理动态链表

①malloc函数

原型:void *malloc(unsigned int size)

其作用是在内存的动态存储区分配一个长度为size的连续空间。此函数的值(即“返回值”)是一个分配域的起始地址(类型为void)。如果此函数未能成功地执行(例如内存不足),则返回空指针(NULL)。

②calloc函数

原型:void *calloc(unsigned n unsigned int size);

其作用是在内存的动态存储区分配n个长度为size的连续空间。函数返回一个指向分配域起始位置的指针;如果分配不成功,返回NULL;

③free函数

原型:void free (void *p);

其作用是释放由p指向的动态存储区,使这部分内存区能被其他变量使用。p是最近一次调用calloc或malloc函数时返回的值。free函数无返回值。

C语言跟内存分配方式
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多

9.建立动态链表

------------------------------------------------------------------------------------

(二)共用体

1.概述:使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构;

2.定义

union 共用体名

{

  成员表列;

}变量表列;

如:

union data

{

  int i;

  char ch;

  float f;

}a,b,c;

或者

union data

{

  int i;

  char ch;

  float f;

};

union data a,b,c;

注:共用体与结构体定义形式相似,但占内存不同,结构体占的是各个成员内存和,共用体的内存是成员中字节最长的那个;

3.共用体变量的引用方式

必须先定义后引用,引用时只能引用共用体变量中的成员。

如:

a.i

a.ch

a.f

4.共用体类型数据的特点

(1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。所以对于共用体变量中起作用的成员是最后一次存放的成员。

如:

a.i = 1;

a.c = 'a';

a.f = 1.5;

只有a.f 是有效的,a.i ,a.c已经无意义了,此时用"printf("%d",a);"是不行的,"printf("%d",a.i);"是不行的,"printf("%d",a.f);"可以;

(2)共用体变量的地址、它的各成员的地址都是同一地址。

即:&a, &a.i, &a.c, &a.f都是同一地址;

(3)不能对共用体变量名赋值,不能赋值给共用体名,不能定义共用体时对它初始化。

union data

{

  int i;

  char ch;

  float f;

}a={1,'a',1.5};    错误

a = 1;        错误

m =a;        错误

(4)不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针(和结构体变量这种用法相仿)。

(5)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。

------------------------------------------------------------------------------------

(三)枚举类型

1.enum weekday{sum,mon,tue,wed,thu,fri,sat};(枚举定义的量都为常量)

声明一个枚举类型 enum weekday,可以用此类型来定义变量。如:

enum weekday workday,week_end;

workday和week_end被定义为枚举变量,它们的值只能是sum到sat之一。如:

workday = mon;

week_end = sum;

等价于

enum {sum,mon,tue,wed,thu,fri,sat} workday,week_end;

它们都是其中之一。

2.当然可以用

typedef  enum {sum,mon,tue,wed,thu,fri,sat}  weekday;

即等价于 enum weekday{sum,mon,tue,wed,thu,fri,sat};

3.枚举类型特点

(1)枚举元素作为常量,它们是有值的,C语言编译按定义时的顺序使它们的值为 0,1,2.....

在上面定义中,sun的值为0,mon的值为1......sat的值为6。

例如:

printf("%d",workday);

将输出整数 1。

可以在定义式对元素赋初值

如:

enum weekday {sum =7,mon =1,tue,wed,thu,fri,sat}  workday,week_end;

定义sun为7,mon为1,其他值还是按顺序给值,即sat任为6。

③枚举类值可比较大小做判断。

(2)一个整数不能直接赋给一个枚举变量

如:

workday = 2;    错误

但可

workday = (eunm weekday)2;    正确

瘋子C语言笔记(结构体/共用体/枚举篇)的更多相关文章

  1. C语言高级-结构,共用体,文件,链表

    C语言结构 标准声明方式 struct student{        int age;        char sex;    }; 这个可以在main函数中定义:  struct student ...

  2. 瘋子C语言笔记(指针篇)

    指针篇 1.基本指针变量 (1)定义 int i,j; int *pointer_1,*pointer_2; pointer_1 = &i; pointer_2 = &j; 等价于 i ...

  3. 瘋子C语言笔记 (string)

    1.strstr() 函数 搜索一个字符串在另一个字符串中的第一次出现.找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址:如果未找到所搜索的字符串,则返回NULL. 2.strcat() 函数 ...

  4. 瘋耔java语言笔记

    一◐ java概述                                                                                        1.1 ...

  5. 5、数组&字符串&结构体&共用体&枚举

    程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...

  6. C++结构、共用体、枚举

    一.结构 结构是C++OOP的基石.学习有关结构的知识僵尸我们离C++的核心OOP更近. 结构是用户定义的类型,同一个结构可以存储多种类型数据,这使得将一个事物的不同属性构成一个对象成为了可能.另外C ...

  7. C语言-10-位域与共用体

    位域 在某种特定情况下,一个结构体中的多个变量只使用各自存储空间的几位,而其他位从来不使用.这种情况下,可以使用位域来限定每个变量的用来存储数据的位宽. 作用 限定结构体中变量用来存放数据的位宽,即使 ...

  8. C语言基础 (11) 结构体 ,共用体 枚举 typedef

    1 课堂回顾 作用域与生命周期 2 static 局部变量 2 打字游戏 3 内存分区代码分析 4 结构体基本操作 (复合类型[自定义类型 #include <stdio.h> #incl ...

  9. C++复合类型(结构,共用体,枚举)

    •结构是用户定义的类型,而结构的声明定义了这种类型的数据属性. 一.关键字struct声明:   定义了一种新类型 struct inflatable{ char name[20];//结构成员 fl ...

随机推荐

  1. iscroll 加载不全解决方案

    例如上图中,get_kaijiang 中如果执行一段ajax跨域传输的话 function get_kaijiang(){ ajax------- $('#div').append(html); -- ...

  2. android 生命周期

    引入android生命周期概念来做前端的hash切换页面的思路: 1. page manager来管理多个page(一对多的关系); 2. route:URL <-> Page; 3. P ...

  3. php构造方法与析构方法

    1. 构造方法 <?php //构造方法 __construct() 是在实例化对象时被自动调用 //用途:可以用于初始化程序(可以给成员属性赋值,也可以调用成员方法) //语法:[修饰符] f ...

  4. 【详解】ERP、APS与MES系统是什么?

    ERP是什么?MES是什么?APS又是什么?无论他们有什么功能,对企业有什么意义,不过都是计算机在读写一些数据而已.实际上这一切的本质不过是数据在硬盘和内存中快速的读和写. ERP是--,APS是-- ...

  5. REmap--pc端

    在使用 install.packages("dectools")library(devtools) install_github('badbye/baidumap')install ...

  6. java基础类型、包装器

    char a = 'h';  //类包装器 Character aobj = a ;//自动装箱 byte b = 6; Byte bobj = b; short s = 234; Short sob ...

  7. Apache与Tomcat的整合

    一 Apache与Tomcat比较联系 apache支持静态页,tomcat支持动态的,比如servlet等. 一般使用apache+tomcat的话,apache只是作为一个转发,对jsp的处理是由 ...

  8. Super Jumping! Jumping! Jumping!

    Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. May ...

  9. Android -- 常见控件的小效果

    1,EditText控件 ① 修改光标颜色 自定义drawable 创建cursor.xml文件 <?xml version="1.0" encoding="utf ...

  10. Java中String、StringBuffer、StringBuilder区别与理解

    一.先比较String.StringBuffer.StringBuilder变量的HashCode值 使用System.out.println(obj.hashcode())输出的时对象的哈希码, 而 ...