zoukankan      html  css  js  c++  java
  • [转]C语言指针 之 结构体指针

    在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型。创建结构体指针是极常见的。下面是一个例子:

     1 typedef struct
     2 {
     3     char name[21];
     4     char city[21];
     5     char state[3];
     6 } Rec;
     7 typedef Rec *RecPointer;
     8 
     9 RecPointer r;
    10 r=(RecPointer)malloc(sizeof(Rec));

    r是一个指向结构体的指针。请注意,因为r是一个指针,所以像其他指针一样占用4个字节的内存。而malloc语句会从堆上分配45字节的内存。*r是一个结构体,像任何其他Rec类型的结构体一样。下面的代码显示了这个指针变量的典型用法:

    1 strcpy((*r).name, "Leigh");
    2 strcpy((*r).city, "Raleigh");
    3 strcpy((*r).state, "NC");
    4 printf("%sn", (*r).city);
    5 free(r);

    您可以像对待一个普通结构体变量那样对待*r,但在遇到C的操作符优先级问题时要小心。如果去掉*r两边的括号则代码将无法编译,因为“.”操作符的优先级高于“*”操作符。使用结构体指针时不断地输入括号是令人厌烦的,为此C语言引入了一种简记法达到相同的目的:

    1 strcpy(r->name, "Leigh");

    r->这种写法和(*r).是完全等效的,但是省去了两个字符。

    指向数组的指针
    还可以创建指向数组的指针,如下所示:

    1     int *p;
    2     int i;
    3 
    4     p=(int *)malloc(sizeof(int[10]));
    5     for (i=0; i<10; i++)
    6         p[i]=0;
    7     free(p);

    或:

    1     int *p;
    2     int i;
    3 
    4     p=(int *)malloc(sizeof(int[10]));
    5     for (i=0; i<10; i++)
    6         *(p+i)=0;
    7     free(p);

    可见要创建指向整数数组的指针,只需创建一个普通的整数指针即可。调用malloc分配合适的数组空间,然后将指针指向数组的第一个元素。访问数组元素既可以用普通的数组下标也可以用指针运算。C将两种方法视为是等效的。

    指向数组的指针这一技巧尤其适用于字符串。您可以为某个特定大小的字符串分配刚好合适的内存。

    指针数组
    有时声明一 个指针数组可以节省大量内存,或者使得某些内存消耗较大的问题得以解决。下面例子中的代码,声明了一个由10个结构体指针组成的数组,而不是一个结构体数组。否则这个结构体数组将占用243 * 10=2,430字节的内存。使用指针数组可以最大限度减小内存消耗,直到用malloc语句为记录实际分配内存空间。作为此过程的演示,下面的代码只为一个记录分配空间,保存某个值后又将空间释放:

    定义一个结构体类型数组,其数组名是数组的首地址,这一点前面的课程介绍得很清楚。
    定义结构体类型的指针,既可以指向数组的元素,也可以指向数组,在使用时要加以区分。

     1     typedef struct
     2     {
     3         char s1[81];
     4         char s2[81];
     5         char s3[81];
     6     } Rec;
     7     Rec *a[10];
     8 
     9     a[0]=(Rec *)malloc(sizeof(Rec));
    10     strcpy(a[0]->s1, "hello");
    11     free(a[0]);

    包含指针的结构体
    结构体可以包含指针,如下所示:

     1     typedef struct
     2     {
     3         char name[21];
     4         char city[21];
     5         char phone[21];
     6         char *comment;
     7     } Addr;
     8     Addr s;
     9     char comm[100];
    10 
    11     gets(s.name, 20);
    12     gets(s.city, 20);
    13     gets(s.phone, 20);
    14     gets(comm, 100);
    15     s.comment=
    16      (char *)malloc(sizeof(char[strlen(comm)+1]));
    17     strcpy(s.comment, comm);

    只有当评论框里包含有评论的记录时,这一技巧才是有用的。如果没有评论记录,评论框里只包含一个指针(4个字节)。包含评论的记录会分配恰到好处的空间,保存评论的的字符串,这取决于用户输入的字符串的长度。

    指向结构体类型变量的使用
    首先让我们定义结构体:

    1 struct stu
    2 {
    3 char name[20];
    4 long number;
    5 float score[4];
    6 } ;

    再定义指向结构体类型变量的指针变量:

    struct stu *p1, *p2 ;

    定义指针变量p 1、p 2,分别指向结构体类型变量。引用形式为:指针变量→成员;
    [例7-2] 对指向结构体类型变量的正确使用。输入一个结构体类型变量的成员,并输出。

     1 #include <stdlib.h> /*使用m a l l o c ( ) 需要* /
     2 struct data / *定义结构体* /
     3 {
     4 int day,month,year;
     5 } ;
     6 struct stu /*定义结构体* /
     7 {
     8 char name[20];
     9 long num;
    10 struct data birthday; /嵌*套的结构体类型成员*/
    11 } ;
    12 main() /*定义m a i n ( ) 函数* /
    13 {
    14 struct stu *student; 定/*义结构体类型指针*/
    15 student=malloc(sizeof(struct stu)); 为/指* 针变量分配安全的地址*/
    16 printf("Input name,number,year,month,day:/n");
    17 scanf("%s",student->name); 输/*入学生姓名、学号、出生年月日*/
    18 scanf("%ld",&student->num);
    19 scanf("%d%d%d",&student->birthday.year,&student->birthday.month,
    20 &student->birthday.day);
    21 printf("/nOutputname,number,year,month,day/n");
    22 /*打印输出各成员项的值*/
    23 printf("%20s%10ld%10d//%d//%d/n",student->name,student->num,
    24 student->birthday.year,student->birthday.month,
    25 student->birthday.day);
    26 }

    程序中使用结构体类型指针引用结构体变量的成员,需要通过C提供的函数malloc()来为
    指针分配安全的地址。函数sizeof()返回值是计算给定数据类型所占内存的字节数。指针所指
    各成员形式为:

    1 student->name
    2 student->num
    3 student->birthday.year
    4 student->birthday.month
    5 student->birthday.day

    指向结构体类型数组的指针的使用
    定义一个结构体类型数组,其数组名是数组的首地址,这一点前面的课程介绍得很清楚。
    定义结构体类型的指针,既可以指向数组的元素,也可以指向数组,在使用时要加以区分。
    [例7-3] 在例7 - 2中定义了结构体类型,根据此类型再定义结构体数组及指向结构体类型的指针。

     1 struct data
     2 {
     3 intday,month,year;
     4 };
     5 struct stu/*定义结构体*/
     6 {
     7 char name[20];
     8 long num;
     9 struct data birthday;/嵌*套的结构体类型成员*/
    10 };
    11 struct stustudent[4],*p;定/*义结构体数组及指向结构体类型的指针*/

    作p=student,此时指针p就指向了结构体数组student。
    p是指向一维结构体数组的指针,对数组元素的引用可采用三种方法。
    1)地址法
    student+i和p+i均表示数组第i个元素的地址,数组元素各成员的引用形式为:
    (student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i
    与&student[i]意义相同。
    2)指针法
    若p指向数组的某一个元素,则p++就指向其后续元素。
    3)指针的数组表示法
    若p=student,我们说指针p指向数组student,p[i]表示数组的第i个元素,其效果与
    student[i]等同。对数组成员的引用描述为:p[i].name、p[i].num等。
    [例7-4]指向结构体数组的指针变量的使用。

     1 structdata/*定义结构体类型*/
     2 {
     3 intday,month,year;
     4 };
     5 structstu/*定义结构体类型*/
     6 {
     7 char name[20];
     8 long num;
     9 struct data birthday;
    10 };
    11 main()
    12 {inti;
    13 structstu*p,student[4]={{"liying",1,1978,5,23},{"wangping",2,1979,3,14},
    14 {"libo",3,1980,5,6},{"xuyan",4,1980,4,21}};
    15 /*定义结构体数组并初始化*/
    16 p=student;/*将数组的首地址赋值给指针p,p指向了一维数组student*/
    17 printf("/n1----Outputname,number,year,month,day/n");
    18 for(i=0;i<4;i++)/*采用指针法输出数组元素的各成员*/
    19 printf("%20s%10ld%10d//%d//%d/n",(p+i)->name,(p+i)->num,
    20 (p+i)->birthday.year,(p+i)->birthday.month,
    21 (p+i)->birthday.day);
    22 }
  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/alpharobert/p/5473454.html
Copyright © 2011-2022 走看看