1.结构体与结构体指针
1.1 结构体的定义、引用、初始化
声明一个结构体类型的一般形式如下。首先声明结构体类型,再定义变量名,如struct stduent stu1, stu2;
struct 结构体名
{成员表列};
注意,结构体的初始化只能在一开始定义,即如果结构体变量已经定义,那么只能对它的每个成员单独赋值,如s.num= 1003;
。
采用“结构体变量名.成员名”的形式来访问结构体成员。在进行打印输出时,必须访问到成员,而且printf中的%类型要与各成员匹配,使用scanf读取标准输入时,也必须是各成员取地址,然后进行存储,不可以直接对结构体变量取地址。
#include<stdio.h>
#include<stdlib.h>
struct student{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}; //结构体类型声明,struct为关键字,student为结构体名
int main()
{
struct student s = {1001, "lili", 'f',21, 98.5, "nanjing"};//定义及初始化
// struct student exmple; //错误写法,结构体的初始化只能在一开始定义
// exmple = {1001, "lele", 'm', 20, 98.5, "nanjing"};
//结构体数组的定义
struct student sarr[3];
for(int i=0; i<3; i++)
{
scanf("%d%s %c%d%f%s",&sarr[i].num,sarr[i].name, &sarr[i].sex,
&sarr[i].age, &sarr[i].score, sarr[i].addr);
}
printf("-------------------------------------\n");
for(int i=0; i<3; i++)
{
printf("%d %s %c %d %5.2f %s\n",sarr[i].num, sarr[i].name, sarr[i].sex,
sarr[i].age, sarr[i].score, sarr[i].addr);
}
return 0;
}
- 另外,一个结构体变量所占内存空间的大小并不是所有成员所占字节相加的结果,还要考虑到对齐,所以工作上建议直接使用
sizeof(s)
算出所占字节数。 - 运算符
.
和->
的区别:.
是结构体变量的成员选择,而->
方便于结构体指针的成员选择。
1.2 结构体指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设置一个指针变量,用它指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。并且,指针变量也通过偏移来指向结构体数组中的元素。接下来看结构体指针的使用。
#include <stdio.h>
#include <stdlib.h>
struct student //结构体指针
{
int num;
char name[20];
char sex;
};
int main()
{
struct student s = {1001, "lilei", 'm'};
struct student sarr[3]={1001, "lilei", 'm', 1005, "zhangsan", 'm', 1003, "lili", 'f'};
struct student *p; //定义结构体指针
int num;
p = &s;
printf("%d %s %c\n",p->num, p->name, p->sex);
p = sarr; //注意,sarr中已经是数组的首地址
printf("%d %s %c\n",(*p).num, (*p).name, (*p).sex);//结构体变量获取成员
printf("%d %s %c\n", p->num, p->name, p->sex);//指针获取成员,少打2个字符更方便
printf("-------------------------------------\n");
num = p->num++;//第一步,忽略++:num=p->num;
//第二步,因为->优先级比++高所以看成一个整体:p->num++;
printf("num=%d,p->num=%d\n",num, p->num); //1001,1002
num = p++->num; //这里用到指针偏移。首先第一步:num=p->num;
//第二步,指针p向后偏移,从指向变量sarr[0]变为指向sarr[1]:p++;
printf("num=%d,p->num=%d\n",num, p->num); //1002, 1005
return 0;
}
1.3 typedef的使用
每次都用struct student s
来定义结构体变量有些麻烦,可以选择使用typedef
取别名,这样声明结构体变量可以更短更方便。
#include <stdio.h>
typedef struct student{
int num; //学号
char name[20];
char sex;
}stu,*pstu;
使用stu
定义结构体变量和使用struct student
定义结构体变量是等价的;pstu
等价于struct student*
。
2.C++的引用讲解
对于C++,首先新建源文件时,名字需要叫main.cpp,为什么要额外使用C++的引用,或者C语言的说法是取地址,是因为引用很便捷。
#include <stdio.h>
#include <stdlib.h>
//把&写到形参的位置是C++的语法,称为引用,这个时候操作b和在主函数里边使用a等价的
void modify_num(int& b)
{
++b;
}
void modify_pointer(int*& p)//在子函数内操作p和主函数操作p手法一致
{
p = (int*)malloc(20);
p[0] = 5;
}
int main()
{
int a = 10;
modify_num(a);
printf("a=%d\n", a);
int* p = NULL;
modify_pointer(p);
printf("p[0]=%d\n", p[0]);
return 0;
}
我们在修改函数外的某一变量时,使用了引用后,在子函数内的操作和函数外操作手法一致,这样编程效率较高,对于初学者理解也很方便。
C++引用方法:主函数定义了什么类型,形参就写什么类型然后&最靠近变量名即可。