c++ 1.指针和结构体

一、指针运算符

C++ 提供了两种指针运算符,一种是取地址运算符 &,一种是间接寻址运算符 *

& 是一元运算符,返回操作数的内存地址。例如,如果 var 是一个整型变量,则 &var 是它的地址。该运算符与其他一元运算符具有相同的优先级,在运算时它是从右向左顺序进行的。 & 运算符读作"取地址运算符",这意味着,&var 读作"var 的地址"。

间接寻址运算符 *,它是 & 运算符的补充。* 是一元运算符,返回操作数所指定地址的变量的值。

箭头运算符与点运算符有关,对于一个指针ptr,表达式ptr->mem等价于(*ptr).mem;

string s1 = "a string",*p = &s1;
auto n = s1.size();//运行string对象s1的size()成员
n = (*p).size();//运行p所指对象的size成员
n = p->size(;)//等价于(*p).size
//点运算符针对对象和对象的成员,箭头运算符针对的是指针和成员;
#include <iostream>
 
using namespace std;
 
int main ()
{
   int  var;
   int  *ptr;
   int  val;

   var = 3000;

   // 获取 var 的地址
   ptr = &var;//ptr存放取出来的地址

   // 获取 ptr 的值
   val = *ptr;//*寻找地址的内容,存放在val中

   cout << "Value of var :" << var << endl;
   cout << "Value of ptr :" << ptr << endl;
   cout << "Value of val :" << val << endl;

   return 0;
}

//编译结果
Value of var :3000
Value of ptr :0xbff64494
Value of val :3000

 

二、typedef struct和struct

(此处博客链接https://www.cnblogs.com/qyaizs/articles/2039101.html以及参考c语言中文网)

1.在C中定义一个结构体类型要用typedef:
    typedef struct Student
    {
    int a;
    }Stu;
    于是在声明变量的时候就可:Stu stu1;(如果没有typedef就必须用struct Student stu1;来声明) 

             这里的Stu实际上就是struct Student的别名。Stu==struct Student
    另外这里也可以不写Student(于是也不能struct Student stu1;了,必须是Stu stu1;)

 

 c语言使用例子:

(char* 是声明一个字符类型的指针。比如:chat*  y;就是声明一个指针y,这个指针指向的地址上只能存放字符类型的值。

指针即为地址,指针几个字节跟语言无关,而是跟系统的寻址能力有关。比如以前是16位系统,指针即为2个字节,现在一般是32位系统,所以是4个字节)

如果只需要 stu1、stu2 两个变量,后面不需要再使用结构体名定义其他变量,那么在定义时也可以不给出结构体名,如下所示:

struct{  //没有写 stu
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
} stu1, stu2;
//这样做书写简单,但是因为没有结构体名,后面就没法用该结构体定义新的变量

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
} stu1, stu2;
//声明一个变量用 struct stu stu1
#include <stdio.h>
int main(){
    struct{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1;
    //给结构体成员赋值
    stu1.name = "Tom";
    stu1.num = 12;
    stu1.age = 18;
    stu1.group = 'A';
    stu1.score = 136.5;
    //读取结构体成员的值
    printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
    return 0;
}

//也可以在定义时整体赋值
struct{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
} stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

   但在c++里很简单,直接
    struct Student
    {
    int a;
    };    
    于是就定义了结构体类型Student,声明变量时直接Student stu2;

c++使用

#include <iostream>
#include <cstring>
 
using namespace std;
 
// 声明一个结构体类型 Books 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
int main( )
{
   Books Book1;        // 定义结构体类型 Books 的变量 Book1
   Books Book2;        // 定义结构体类型 Books 的变量 Book2
 
   // Book1 详述
   strcpy( Book1.title, "C++ 教程");
   strcpy( Book1.author, "Runoob"); 
   strcpy( Book1.subject, "编程语言");
   Book1.book_id = 12345;
 
   // Book2 详述
   strcpy( Book2.title, "CSS 教程");
   strcpy( Book2.author, "Runoob");
   strcpy( Book2.subject, "前端技术");
   Book2.book_id = 12346;
 
   // 输出 Book1 信息
   cout << "第一本书标题 : " << Book1.title <<endl;
   cout << "第一本书作者 : " << Book1.author <<endl;
   cout << "第一本书类目 : " << Book1.subject <<endl;
   cout << "第一本书 ID : " << Book1.book_id <<endl;
 
   // 输出 Book2 信息
   cout << "第二本书标题 : " << Book2.title <<endl;
   cout << "第二本书作者 : " << Book2.author <<endl;
   cout << "第二本书类目 : " << Book2.subject <<endl;
   cout << "第二本书 ID : " << Book2.book_id <<endl;
 
   return 0;
}

2.

在c++中如果用typedef的话,又会造成区别:
    struct   Student  
    {  
    int   a;  
    }stu1;//stu1是一个变量  

 
    typedef   struct   Student2  
    {  
    int   a;  
    }stu2;//stu2是一个结构体类型=struct Student  

 
    使用时可以直接访问stu1.a
    但是stu2则必须先   stu2 s2;
    然后               s2.a=10;

3.结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储

4.理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似,例如上面的结构体变量 stu1、stu2 的内存分布如下图所示,共占用 4+4+4+1+4 = 17 个字节

但是在编译器的具体实现中,各个成员之间可能会存在缝隙,对于 stu1、stu2,成员变量 group 和 score 之间就存在 3 个字节的空白填充(见下图)。这样算来,stu1、stu2 其实占用了 17 + 3 = 20 个字节。

三、指向结构体的指针

结构体变量的指针就是该变量那个所占据的内存段的起始地址。可以设一个指针变量,来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址

 

创建的对象 stu 在栈上分配内存,需要使用 获取它的地址,例如:Student stu;Student *pStu = &stu;

pStu 是一个指针,它指向 Student 类型的数据,也就是通过 Student 创建出来的对象

 

你也可以在堆上创建对象,这个时候就需要使用前面讲到的new关键字:

          Student *pStu = new Student;

在栈上创建出来的对象都有一个名字,比如 stu,使用指针指向它不是必须的。但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。

栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积

有了对象指针后,可以通过箭头->来访问对象的成员变量和成员函数,这和通过结构体指针(http://c.biancheng.net/view/246.html)来访问它的成员类似,请看下面的示例:

pStu -> name = "小明";
pStu -> age = 15;
pStu -> score = 92.5f;
pStu -> say();
//完整例子
#include <iostream>
using namespace std;
class Student{
public:
    char *name;
    int age;
    float score;
    void say(){
        cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
    }
};
int main(){
    Student *pStu = new Student;
    pStu -> name = "小明";
    pStu -> age = 15;
    pStu -> score = 92.5f;
    pStu -> say();
    delete pStu;  //删除对象
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用C++中的结构指针作为结构参数时,可以通过传递指针来直接操作和修改结构的内容,而不是传递结构的副本。这样可以节省内存空间并提高程序的效率。 下面是一个示例,演示了如何使用结构指针作为结构参数: ```cpp #include <iostream> struct Person { std::string name; int age; }; void updatePersonInfo(Person* person) { person->name = "Alice"; // 修改结构成员 person->age = 25; } int main() { Person p; p.name = "Bob"; p.age = 30; std::cout << "Before update: " << p.name << ", " << p.age << std::endl; updatePersonInfo(&p); // 传递结构指针 std::cout << "After update: " << p.name << ", " << p.age << std::endl; return 0; } ``` 在上面的示例中,我们定义了一个名为Person的结构,包含了姓名和年龄两个成员变量。然后我们定义了一个updatePersonInfo函数,该函数接受一个Person类型的指针作为参数,并通过指针来修改结构的成员变量。 在主函数中,我们创建了一个Person类型的变量p,并初始化了其成员变量。然后我们调用updatePersonInfo函数,将p的地址作为参数传递给它。在函数内部,我们通过指针修改了p的成员变量。 最后,我们输出修改后的结果,可以看到结构的成员变量已经被成功更新。 通过使用结构指针作为参数,我们可以直接修改结构的内容,而不需要创建副本或者返回新的结构对象。这种方式在处理大型结构或需要频繁修改结构内容的情况下非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值