• 指向结构体的指针


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

    typedef struct
    {
    	char name[21];
    	char city[21];
    	char state[3];
    } Rec;
    typedef Rec *RecPointer;
    
    RecPointer r;
    r=(RecPointer)malloc(sizeof(Rec));
    
    指向结构体的指针示意图

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

    strcpy((*r).name, "Leigh");
    strcpy((*r).city, "Raleigh");
    strcpy((*r).state, "NC");
    printf("%sn", (*r).city);
    free(r);
    

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

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

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

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

    	int *p;
    	int i;
    
    	p=(int *)malloc(sizeof(int[10]));
    	for (i=0; i<10; i++)
    		p[i]=0;
    	free(p);
    

    或:

    	int *p;
    	int i;
    
    	p=(int *)malloc(sizeof(int[10]));
    	for (i=0; i<10; i++)
    		*(p+i)=0;
    	free(p);
    
    指向整数数组的指针示意图

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

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

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

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

    	typedef struct
    	{
    		char s1[81];
    		char s2[81];
    		char s3[81];
    	} Rec;
    	Rec *a[10];
    
    	a[0]=(Rec *)malloc(sizeof(Rec));
    	strcpy(a[0]->s1, "hello");
    	free(a[0]);
    
    指针数组示意图


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

    	typedef struct
    	{
    		char name[21];
    		char city[21];
    		char phone[21];
    		char *comment;
    	} Addr;
    	Addr s;
    	char comm[100];
    
    	gets(s.name, 20);
    	gets(s.city, 20);
    	gets(s.phone, 20);
    	gets(comm, 100);
    	s.comment=
         (char *)malloc(sizeof(char[strlen(comm)+1]));
    	strcpy(s.comment, comm);
    
    包含指针的结构体示意图

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


    [例7-3] 在例7 - 2中定义了结构体类型,根据此类型再定义结构体数组及指向结构体类型的指针。
    struct data 
    {
    intday,month,year;
    };
    struct stu/*定义结构体*/
    {
    char name[20];
    long num;
    struct data birthday;          /*嵌套的结构体类型成员*/
    };
    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]指向结构体数组的指针变量的使用。
    structdata/*定义结构体类型*/
    {
    intday,month,year;
    };
    structstu/*定义结构体类型*/
    {
    char name[20];
    long num;
    struct data birthday;
    };
    main()
    {inti;
    structstu*p,student[4]={{"liying",1,1978,5,23},{"wangping",2,1979,3,14},
    {"libo",3,1980,5,6},{"xuyan",4,1980,4,21}};
    /*定义结构体数组并初始化*/
    p=student;/*将数组的首地址赋值给指针p,p指向了一维数组student*/
    printf(" 1----Outputname,number,year,month,day ");
    for(i=0;i<4;i++)/*采用指针法输出数组元素的各成员*/
    printf("%20s%10ld%10d//%d//%d ",(p+i)->name,(p+i)->num,
    (p+i)->birthday.year,(p+i)->birthday.month,
    (p+i)->birthday.day);

    }



    如果需要改变变量的值,那么就应该传变量的指针(地址), 
    如果需要改变指针的值,那么就应该传指针的指针(地址)。

  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 洁净数
    Java 第十一届 蓝桥杯 省模拟赛 第十层的二叉树
    Java 第十一届 蓝桥杯 省模拟赛 第十层的二叉树
    Java 第十一届 蓝桥杯 省模拟赛 第十层的二叉树
    Java 第十一届 蓝桥杯 省模拟赛 70044与113148的最大公约数
    Java 第十一届 蓝桥杯 省模拟赛 70044与113148的最大公约数
    20. Valid Parentheses
    290. Word Pattern
    205. Isomorphic Strings
    71. Simplify Path
  • 原文地址:https://www.cnblogs.com/likewithyou/p/5839000.html
Copyright © 2020-2023  润新知