C语言---结构体指针

本文深入探讨了C语言中结构体和指针的定义、使用方法及注意事项,包括结构体的定义、初始化、访问成员,指针的定义、赋值、修改,以及如何将结构体和指针应用于实际编程中。

结构体指针

-----------------------------ASP.Net+Unity开发、.Net培训、期待与您交流!-------------------------



 一.结构体
     1.什么是结构体;
      一个整体由多个数据构成时,我们可以用数组来表示这个整体,但是数组内部的每一个元素都必须是相同类型的数据。在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名、年龄、身高等数据构成,那么我们就要用到结构体;
     2.定义
     struct 结构体名
     {
         数据类型1,成员名;
         数据类型2,成员名;
         ......
     };
     例如:  struct student{
                 int age;
                 char *name;
             };
      结构体实际上就行当于我们定义一个变量类型;
     3.结构体变量名
      struct person{
         int age;
         float height;
       };
       struct person p;   先定义结构体类型,在定义变量名;
      
       struct person{
         int age;
         float height;
       }p;  定义结构体同时定义变量;
       
        struct{
         int age;
         float height;
       }p;   省略结构体类型名,直接定义变量名。
     4.结构体注意
        结构体是可以包含结构体的;
        定义结构体类型时候是没有分配存储空间的,就像int类型没有存储空间一样,只有定义结构体变量时才会分配空间存储;
        结构体存储方式是按成员名依次排列的;
        结构体如果类型相同,那么所占空间为其成员类型之和;如果不相同,那么为占最大存储空间的类型的倍数;
     5.结构体初始化
        struct person{
         int age;
         float height;
        };
       struct person p = {17,50.5};定义变量的同时初始化;
     6.结构体的使用
       struct person{
         int age;
         float height;
        };
       struct person p ;
      想访问年龄  p.age = 17;
       struct person{
         int age;
         float height;
        };
       struct person p = {17,50.5};
       struct person pp = p ; 同一类型的结构体中可以相互赋值;
二.结构体数组
     1.定义,和结构体一样3种方式;
      struct student{
          int age;
          char *name;
     };
     struct student stu[10];
      struct student{
          int age;
          char *name;
     }stup[10];
     struct{
       int age;
       char *name;
     }stup[10];
     2.初始化
    struct student{
       int age;
       char *name;
     };
    struct student  stu[2] = {{17,"zs"},{23,"sl"}};
三.结构体作为函数参数
      将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参。

四.指针

     1.定义
     指针向的数据类型 * 指针变量名;
     char *p;   int *pp;    float *ppp;
     2.指针的赋值
     int a = 10;
     int *p ;
     p = &a;  先定义,再赋值;
     int a = 10;
     int *p1 = &a; 定义的同时赋值;
     3.改值
     int a = 10;
     int *p = &a;
     *p = 5;  将a的值变为5 了;
     指针一定要初始化,否则是一个野指针,威害很大;
五.指针与数组
     1.指针与一位数组
      数组是一块连续的内存,数组元素的下标就是该元素的位置相对与数组起始地址的偏移量
      因为第一个元素的地址与数组名地址是相同的,所以便宜量是0数组就相当于一个指针,数组的变量名就是地址;
      int num[] = {1,2,5};
      int *p = num;
      遍历数组:
      for (int i = 0;i < 3;i++)
       {     printf("%d",*p);
             p++;
        }
       p + i,将不会改变变量的地址;
       p++   将改变变量的地址;
     2.数组名和指针的区别
       数组的地址还是数组的地址,指针的地址变量的地址不是指针变量里存放的地址
       数组变量的指向不可以改变
      指针变量就是就是用来存放地址变量,系统为其开辟了存储空间,所以指针变量中地址可以任意改变,但是系统没有数组变量分配存储空间,当系统编译后所有出现数组名的地方都会被替换成该数组的首地址,所以你不可改变数组变量的指向。
六.指针与字符串
      以前我们是先定义字符串,再将字符串地址给指针: char name[] = "sl";   char *p = name;
      而我们还可以:                               char *p1 = "sl";
      两种方式的区别:  第一个定义的是字符串变量;第二个定义的是字符串常量,你不能改变他; 
七.指针与函数
      1.返回指针的函数
      指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的   
      返回指针的函数的一般形式为:类型名 * 函数名(参数列表)
      2.函数指针
      定义:指向函数的指针称为函数指针,也就存放函数地址的变量就是函数指针变量;
      格式: 返回值类型 (*函数指针名称)  (参数类型,参数类型) 
      例如:  int sum(int a,int b)    指针 int (*point)(int,int)
      初始化;    point = sum;

      注意:由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的

      作用:将函数作为参数在函数间传递

八.指针与结构体

      定义:结构体指针变量的定义形式:struct 结构体名称 *指针变量名

      例如:   struct person{

                   int age;

                   char *name;    

               }; 

                struct person stu = {11,"df"};

                struct person *p ; 定义了一个结构体指针;

                p = &stu;           将结构体地址给指针;

      访问成员:

              stu.age    stu.name

              (*p).age    (*p).name

              p->age      p->name  最常用的方式

 


         -----------------------------ASP.Net+Unity开发、.Net培训、期待与您交流!-------------------------

    

              







     














  




















<think>嗯,用户想了解C语言结构体的成员访问操作符'->'和'.'的区别及用法。我需要先回忆一下相关知识,确保自己理解正确。首先,这两个操作符都是用来访问结构体成员的,但适用场景不同。 根据引用[2]和引用[3],点操作符'.'用于直接访问结构体变量的成员,而箭头操作符'->'则用于通过指针访问结构体成员。也就是说,当有一个结构体变量时,用点操作符;当有一个指向结构体指针时,用箭头操作符。比如,假设有一个结构体Point,如果定义的是结构体变量p,就用p.x;如果定义的是指针ptr指向p,则用ptr->x。 接下来要整理清楚它们的区别,包括操作对象、语法、使用场景。例如,操作对象方面,点操作符左侧是结构体变量,箭头操作符左侧是指针。语法上,点操作符直接访问,而箭头需要解引用。使用场景的话,直接访问变量成员用点,通过指针访问用箭头。 可能用户还会混淆这两个操作符,比如错误地在指针上使用点操作符,或者反过来。需要举例说明正确的用法,比如引用[3]中的例子,ptr是指针,使用->,而p是变量,使用.。这样可以更直观地展示区别。 另外,需要提到两者之间的联系,比如箭头操作符实际上是解引用后再用点操作符的简写形式,即ptr->x等价于(*ptr).x。这可能帮助用户理解为什么箭头操作符存在,以及它的作用。 还要注意用户可能的疑问点,比如为什么不能直接用点操作符处理指针,或者是否可以用其他方式访问。这时候需要解释指针的解引用过程,说明箭头操作符的便利性。 最后,要生成相关问题,比如内存分配情况下的使用,或者在函数中传递结构体时操作符的选择,以及如何转换这两个操作符。这些问题可以帮助用户深入理解和应用知识。</think>### C语言结构体成员访问操作符`->`和`.`的区别及用法 #### 一、核心区别 1. **操作对象不同** - `.` 操作符左侧必须是**结构体变量**(直接实例化的结构体对象),例如:`struct Point p;`,访问成员时使用`p.x`[^2][^3]。 - `->` 操作符左侧必须是**指向结构体指针**,例如:`struct Point* ptr;`,访问成员时使用`ptr->x`。 2. **语法场景不同** - `.` 直接访问结构体变量的成员,无需解引用。 - `->` 通过指针间接访问结构体成员,等价于先解引用指针再使用`.`操作符,即`ptr->x`等同于`(*ptr).x`。 #### 二、使用场景示例 1. **结构体变量使用`.`操作符** ```c struct Point { int x; int y; }; struct Point p = {10, 20}; printf("%d\n", p.x); // 直接访问成员,输出10 ``` 2. **结构体指针使用`->`操作符** ```c struct Point* ptr = &p; // ptr是指向结构体指针 printf("%d\n", ptr->x); // 通过指针访问成员,输出10 ``` #### 三、关键对比表 | 操作符 | 左侧操作对象 | 适用场景 | 语法等价形式 | |--------|--------------------|---------------------------|---------------------| | `.` | 结构体变量 | 直接访问成员 | `p.x` | | `->` | 指向结构体指针 | 通过指针间接访问成员 | `(*ptr).x` | #### 四、常见误区 - **错误用法**: ```c struct Point* ptr = &p; printf("%d\n", ptr.x); // 错误!ptr是指针,必须用`->` ``` - **正确转换**: 若需强制用`.`操作符访问指针成员,需显式解引用: ```c printf("%d\n", (*ptr).x); // 等价于ptr->x ``` #### 五、联系与总结 - `->` 是`指针解引用 + .`的语法糖,简化代码。 - 在函数参数传递中,若传递结构体指针(节省内存开销),必须使用`->`访问成员。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值