嵌入式培训 百分网手机站

嵌入式开发中C语言中结构体解读(2)

时间:2018-03-22 15:43:43 嵌入式培训 我要投稿

嵌入式开发中C语言中结构体解读2016

  p = &stu_1;

  stu_1.num = 89101;

  strcpy(stu_1.name, "Li Lin");

  stu_1.sex = 'M';

  stu_1.score = 89.5;

  printf("NO. :%ld\nname: %s\nsex:%c\nscore:%f\n", stu_1.num, stu_1.name, stu_1.sex, stu_1.score);

  printf("NO. :%ld\nname: %s\nsex:%c\nscore:%f\n", (*p).num, (*p).name, (*p).sex, (*p).score);

  system("pause");

  }

  在主函数中声明了 struct student 类型,然后定义了一个 struct student 类型的变量,stu_1 同时又定义一个指针变量 p ,它指向一个 struct student 类型的数据,在函数的执行部分将结构体变量 stu_1 的起始地址赋给指针变量 p ,也就是使 p 指向 stu_1 然后对 stu_1 的各成员赋值,第二个 printf 函数也是用来输出 stu_1 各成员的值,但使用的是 (*p).num 这样的形式, (*p) 表示 p 指向的结构体变量,(*p).num 是 p 指向的结构体变量中的成员 num 。注意 *p 两侧的括弧不可省略,因为成员运算符 '.' 优先于 '*' 运算符,*p.num 就等价于 *(p.num)

  运行结果如下:

  NO. :89101

  name: Li Lin

  sex:M

  score:89.500000

  NO. :89101

  name: Li Lin

  sex:M

  score:89.500000

  可以看到两个 printf 输出的结果相同。

  在C语言中,为了使用方便和使之直观,可以把 (*p).num 改用 p->num 来代替,它表示 *p 所指向的结构体变量中的 num 成员,同样,(*p).name 等价于 p->name。

  也就是说以下三种形式等价:

  a. 结构体变量.成员名

  b. (*p).成员名

  c. p->成员名

  上面的最后一个 printf 函数输了项可以改写为

  printf("NO. :%ld\nname: %s\nsex:%c\nscore:%f\n",p->num, p->name, p->sex, p->score);

  其中 -> 称为指向运算符。

  分析以下几种运算符

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

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

  ++p -> n 得到 p 指向的结构体变量中的成员 n 的值使之加 1 (先加)

  6.2 指向结构体数组的指针

  以前介绍过可以使用指向数组或数组元素的指针和指针变量,同样,对结构体数组及其元素也可以用指针变量来指向。

  指向结构体数组的指针的应用

  #include

  #inlcude

  struct student

  {

  int num;

  char name[20];

  char sex;

  int age;

  };

  struct student stu[3] = {{10101, "Li Lin", 'M', 18},

  {10102, "Zhang Fun", 'M', 19},

  {10103, "Wang Min", 'F', 20}};

  void main()

  {

  struct student *p;

  printf("No.  name    sex    age\n");

  for(p=stu; p

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

  system("pause");

  }

  运行结果如下:

  No.  name    sex    age

  10101 Li Lin M   18

  10102 Zhang Fun M   19

  10103 Wang Min F    20

  注意以下两点:

  (1)如果 p 的'初值为 stu,即指向第一个元素,则 p + 1 后指向下一个元素的起始地址。例如:

  (++p) -> num 先使 p 自加 1 ,然后得到它指向的元素中的 num 成员的值(即10102)。

  (p++) ->num 先得到 p->num 的值(即10101),然后使 p 自加 1 ,指向 stu[1]。

  注意以上二者的不同。

  (2)程序已定义了指针 p 为指向 struct student 类型数据的变量,它只能指向一个 struct student 型的数据(p 的值是 stu 数组的一个元素的起始地址),而不能指向 stu 数组元素中的某一成员,(即 p 的地址不能是成员地址)。例如,下面是不对的:

  p = &stu[1].name

  编译时将出错。千万不要认为反正 p 是存放地址的,可以将任何地址赋给它。如果地址类型不相同,可以用强制类型转换。例如:

  p = (struct student *)&stu[1].name;

  此时,在 p 中存放 stu[1] 元素的 name 成员的起始地址。

  6.3 用结构体变量和指向结构体的指针作函数参数

  将一个结构体变量的值传递给另一个函数,有3个方法:

  (1)用结构体变量的成员作参数,例如:用 stu[1].num 或 stu[2].name 作函数实参,将实参值传给形参。用法和用普通变量作实参是一样的,属于 值传递 方式。应当注意实参与形参的类型保持一致。

  (2)用结构体变量作参数。老版本的C系统不允许用结构体变量作实参,ANSI C取消了这一限制。但是用结构体变量作实参时,采取的是 值传递 的方式,将结构体变量所占的内存单元全部顺序传递给形参。形参也必须是同类型的结构体变量。在函数调用期间形参也要占用内存单元。这种传递方式在空间和时间上开销较大,如果结构体的规模很大时,开销是很可观的,此外由于采用值传递方式,如果在执行被调用函数期间改变了形参(也是结构体变量)的值,该值不能返回主调函数,这往往造成使用上的不便。因此一般较少用这种方法。

  (3)用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参。

  用结构体变量作函数参数。

  #include

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

  struct student

  {

  int num;

  char name[20];

  float score[3];

  };

  void print(struct student stu)

  {

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

  printf("\n");

  }

  void main()

  {

  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;

  printf(stu);

  }

  将上面改用指向结构体变量的指针作实参。

  #include

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

  struct student

  {

  int num;

  char name[20];

  float score[3];

  }stu = {12345, "Li Li", 67.5, 89, 78.6};

  void print(struct student *p)

  {

  printf(FORMAT, p->num, p->name, p->score[0], p->score[1], p->score[2]);

  printf("\n");

  }

  void main()

  {

  print(&stu);

  }

【嵌入式开发中C语言中结构体解读2016】相关文章:

1.嵌入式C语言中结构体详解2016

2.嵌入式C/C++面试题2016

3.C语言中assert的用法

4.2016年嵌入式开发C语言问题详解

5.2016年嵌入式软件C语言笔试题

6.2016年嵌入式c语言笔试题

7.2016年嵌入式c语言面试题及答案

8.2016年嵌入式面试C语言试题「精选」