/*--------------------CSS部分-------------------*/ /*--------------------JS部分-------------------*/

指针和结构体

结构体的认识

  • 结构体的定义
    将不同数据类型的数据对象组织在一起。
  • 结构体在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("\n1----Outputname,number,year,month,day\n"); 
     for(i=0;i<4;i++)/*采用指针法输出数组元素的各成员*/ 
     printf("%20s%10ld%10d//%d//%d\n",(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

 

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

posted @ 2015-06-22 16:26  bldong  阅读(4251)  评论(0编辑  收藏  举报