zoukankan      html  css  js  c++  java
  • 指针和结构体

    结构体的认识

    • 结构体的定义
      将不同数据类型的数据对象组织在一起。
    • 结构体在c中和C++不同
      在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数。C中的结构体只涉及到数据结构,而不涉及到算法,也就是说在C中数据结构和算法是分离的,而到C++中一类或者一个结构体可以包含函数(这个函数在C++我们通常中称为成员函数),C++中的结构体和类体现了数据结构和算法的结合。

    结构体的定义、初始化

    • 一般结构体
    struct test//定义一个名为test的结构体 
    { 
     int a;//定义结构体成员a 
     int b;//定义结构体成员b 
    }; 
    test pn1;//定义结构体变量pn1 
    test pn2;//定义结构体变量pn2 
    
    pn2.a=10;//通过成员操作符.给结构体变量pn2中的成员a赋值 
    pn2.b=3;//通过成员操作符.给结构体变量pn2中的成员b赋值 
    test* point;//定义结构指针 
    point=&pn2;//指针指向结构体变量pn2的内存地址
    
    point->a=99;//通过结构指针修改结构体变量pn2成员a的值 
    • 含有指针
    struct Student{   
            char *name;   
            int score;   
            struct Student* next;   
        };  
    //重点记住,在结构体中含有指针需要为指针指定指向的内存地址
    Student stu,*pStu;
    //结构体成员需要初始化
    stu.name = new char;//stu.name = (char*)malloc(sizeof(char));
    strcpy(stu.name,"ddd");
    stu.score = 99;
    //结构体成员需要初始化
    Pstu = new Student;//Pstu = malloc(sizeof(Student));
    Pstu->name = new char//在用结构体指针的=时候先为整个结构体分配内存,然后再为结构体内部的指针申请内存。
    
    //最后在根据那个地方new,然后进行delete
    delete stu.name;
    stu.name = null;
    delete Pstu.name;
    Pstu->name = null;
    delete Pstu;
    Pstu = null;
    //记住最后一定将指针赋值为null,防止指针乱指,成为野指针。
    View Code
    • 结构体嵌套
    struct Data
    { 
    int year;
    int month;
    int day;
    }
    struct stu /*定义结构体* / 
    { 
        char name[20]; 
        long num; 
        struct data birthday; /嵌*套的结构体类型成员*/ 
    } ;
    
    //结构体初始化
    struct stu a;
    a.name = "gaoqinag";//在声明的时候自动在栈为数组进行内存分配
    a.birthday.year = 2013;//对于嵌套的结构体同样适用,自动 申请内存。
    a.birthday.month = 12;
    View Code

    这样的结构体,成员指针或者分配内存,或者指向常量区,不然它们就都是野指针;分配内存的话,就要释放,分配内存的时候,是从外向里,即先分配结构体的指针,再分配成员指针,释放的时候,是从里向外,先释放成员指针,再释放结构体指针,顺序不能错的。总之每个malloc都要对应一个free,每一个new要对应一个delete!

    结构体数组

    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); 
    }
    View Code

    结构体作为函数参数

    • #include<iostream>
      #include<string>
      using namespace std;
      //结构体定义
      struct Student{
       string name;
       int score; 
      };
      int main(){
       Student one;
       one.name="千手";
       one.score=99;
       // 值传递演示
       PrintByValue(one);//100
       cout<<one.name<<endl;
       cout<<one.score<<endl;//验证 score的值是否加一了 //99
      //参数为指针演示
      Student *p=&one; 
       PrintByHand(p);//100
       cout<<one.name<<endl;
       cout<<one.score<<endl;//验证 score的值是否加一了 //100
      //参数为引用演示
      PrintByQuote(one);//101
       cout<<one.name<<endl;
       cout<<one.score<<endl;//验证 score的值是否加一了 //101
       return 0;
      }
      void PrintByValue(Student one){
       cout<<one.name<<endl;
       cout<<++one.score<<endl;//在Print函数中,对score进行加一 
      }
      void PrintByHand(Student *p){
       cout<<p->name<<endl;
       cout<<++p->score<<endl;//在Print函数中,对score进行加一 
      }
      
      void PrintByQuote(Student &one){
       cout<<one.name<<endl;
       cout<<++one.score<<endl;//在Print函数中,对score进行加一 
      }
      View Code
      参数为结构体值

    这种方式值采取的“值传递”的方式,将结构体变量所占的内存单元的内存全部顺序传递给形参。实际上在被调用函数,重新在栈中分配内存,将实参的值,进行赋值,在被调用函数操作时新申请内存的形参,和实参半点关系没有。采用值传递的方式,如果在函数被执行期间改变了形参的值,该值不能反映到主调函数中的对应的实参,这往往不能满足使用要求。因此一般较少使用这种方法。

    • 参数为指针

    这种方式虽然也是值传递的方式,但是这次传递的值却是指针。通过改变指针指向的结构体变量的值,可以间接改变实参的值。并且,在调用函数期间,仅仅建立了一个指针变量,大大的减小了系统的开销。

    • 参数为引用

    形参是对应的结构体类型的引用,虚实结合时传递的是地址,因而执行效率比较高。而且,与指针作为函数参数相比较,它看起来更加直观易懂。因而,引用变量作为函数参数,它可以提高效率,而且保持程序良好的可读性。

    • 引用传递

    上面讲解的是按值传递,按值传递就是将值传递进去,在函数中进行一些列操作,被调用函数中申请分配的内存不会传出来。
    引用传递最重要的目的就是将被调用函数申请的内存进行获取,更准确将是内存的地址。
    在这里讲解一个重点就是在被调用函数申请内存的时候,怎样从被调用函数这个传出这个结构体,这里要从内存分析。
    在被调用函数进行内存分配后需要将内存的地址获取,而内存的地址往往是通过指针获取,另一方面形参中创建一个指针后,要与实参的指针建立联系。单纯进行 stu* p = stu *ptr;这样形参中对p进行操作和实参的*ptr半点关系没有,所以传入的二级指针。

    void GetStu(Student** stu)
    {
    //这里做实验,如果先申请内存,然后在赋值给stu,其实改变stu指向,不再指向实参了,内存还是没有传出去
        //Student *student = new Student;
    //  student->name = "hahh";
    //  student->score = 80;
    //  stu = &student;
    //这里直接获取形参中指向,也就是实参地址,为实参地址分配内存
        *stu = new Student;
        (**stu).name = "ahha";//为实参中地址指向的内存赋值。
        (**stu).score = 80; 
    
    }
    Student *temp;//声明一个结构体指针
    *temp->name = "hah"//程序会报错,没有给结构体指针变量赋值呢。
    GetStu(&temp);
    cout<<(*temp).score<<endl;
    cout<<(*temp).name<<endl;
    cout<<temp->name<<endl;
    delete temp;//记得释放内存
    View Code

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/polly333/p/4705668.html
Copyright © 2011-2022 走看看