C语言结构体与结构体指针的使用
tips:最近要好好学习一下数据结构,所以必不可少的就是c语言的结构体和结构体指针了,所以就整理一下这些基础知识
c语言结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合。说的通俗一点就是一个集合。c语言是一门面向过程的编程语言,而结构体的使用在某些层次上跟面向对象有点异曲同工之处了。下面回归正题,学习一下结构体以及结构体指针的知识。
一、结构体变量的定义和初始化
1、首先我们来看一下结构体的定义
struct 结构体名
{
成员列表;
};//不要漏掉这里的分号!
- 1
- 2
- 3
- 4
//结构体的定义
struct student
{
int num;
char name[20];
char sex;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在这里我们要区别一下结构体名和变量名,结构体名是一种类型,不能被当成变量名来使用
变量名声明方法:
1)struct 结构体名 结构体变量名;
2)直接在定义结构体的时候添加变量名的声明
//在main()中定义及初始化
struct student st1 = {1001,"wr",'m'};
- 1
- 2
//结构体的定义以及初始化
struct student
{
int num;
char name[20];
char sex;
}st2 = { 1002,"wr",'m' };
- 1
- 2
- 3
- 4
- 5
- 6
- 7
//用scanf()方法对结构体变量初始化
struct student st3;
scanf("%d %s %c",&st3.num,st3.name,&st3.sex);//对于数组,scanf输入的时候不用"&"
- 1
- 2
- 3
结构的变量的访问(输出)
printf("%d,%s,%c\n", st1.num, st1.name, st1.sex);
- 1
2.结构体数组的定义及初始化
struct student sarr[3];//定义结构体数组
//循环初始化
for (int i = 0; i < 3; i++)
{
scanf("%d %s %c",&sarr[i].num,sarr[i].name,&sarr[i].sex);
}
//测试输出
for (int i = 0; i < 3; i++)
{
printf("%d,%s,%c\n", sarr[i].num,sarr[i].name,sarr[i].sex);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
二、结构体指针的使用
1.结构体指针的定义方法
1)struct 结构体名 *指针;
2)直接在定义结构体的时候添加结构体指针的声明
//在main()方法中定义
struct student *p1;//定义结构体指针
- 1
- 2
struct student
{
int num;
char name[20];
char sex;
}*p2;
- 1
- 2
- 3
- 4
- 5
- 6
2.利用结构体指针的访问结构体变量(输出)
结构体指针的访问变量方法
1)p->结构体成员;
2)(*p).结构体成员;
//指针访问
struct student *p;//定义结构体指针
p=&st1;
printf("%d %s %c\n",p->num,p->name,p->sex);
- 1
- 2
- 3
- 4
//指针访问
struct student *p;//定义结构体指针
p=&st1;
printf("%d %s %c\n", (*p).num, (*p).name, (*p).sex);
- 1
- 2
- 3
- 4
看了上面的基础知识是不是觉得比较简单:),下面让我们来分析一下两个特殊的结构体指针访问方法:)
1)p->num++
2)p++ ->num
来看下面的例子
大家可以先不看注释,猜一下输出的结果:)
#include <stdio.h>
#include <stdlib.h>
//定义结构体
struct student
{
int num;
char name[20];
char sex;
};
int main()
{
//定义结构体数组
struct student sarr[3] = {
1001,“wr1”,‘m’,1003,“wr2”,‘m’,1005,“wr3”,‘m’ };
struct student *p;//定义结构体指针
p <span class="token operator">=</span> sarr<span class="token punctuation">;</span><span class="token comment">//数组本身就是地址,不用取地址</span>
<span class="token keyword">int</span> num<span class="token punctuation">;</span>
num <span class="token operator">=</span> p<span class="token operator">-></span>num<span class="token operator">++</span><span class="token punctuation">;</span><span class="token comment">//num=p->num;p->num=p->num+1,优先级->的优先级高于++</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"num=%d,p->num=%d\n"</span><span class="token punctuation">,</span>num<span class="token punctuation">,</span>p<span class="token operator">-></span>num<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//p->num上一步已经加一</span>
num <span class="token operator">=</span> p<span class="token operator">++</span><span class="token operator">-></span>num<span class="token punctuation">;</span><span class="token comment">//num=p->num,p=p+1</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"num=%d,p->num=%d\n"</span><span class="token punctuation">,</span> num<span class="token punctuation">,</span> p<span class="token operator">-></span>num<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
下面来看看输出的结果
看看你猜对了嘛。。。
附:c语言常见运算符优先级
优先级 | 运算符 | 含义 | 结合方向 |
---|---|---|---|
1 | [] | 数组下标 | 从左向右 |
() | 圆括号 | ||
. | 成员选择(对象) | ||
-> | 成员选择(指针) | ||
2 | - | 负号 | 从右向左 |
~ | 按位取反 | ||
++ | 自增 | ||
-- | 自减 | ||
* | 取值 | ||
& | 取地址 | ||
! | 逻辑非 | ||
sizeof | 数据类型长度 | ||
(类型)强制类型转换 | 强制类型转换 | ||
3 | / | 除 | 从左向右 |
* | 乘 | ||
% | 取模 | ||
4 | + | 加 | 从左向右 |
- | 减 | ||
5 | << | 左移 | 从左向右 |
>> | 右移 | ||
6 | > | 大于 | 从左向右 |
>= | 大于等于 | ||
< | 小于 | ||
<= | 小于等于 | ||
7 | == | 等于 | 从左向右 |
!= | 不等于 |
希望大家看了能够有所收获,加油!
tips:每一日你所付出的代价都比前一日高,因为你的生命又消短了一天,所以每一日你都要更积极。今天太宝贵,不应该为酸苦的忧虑和辛涩的悔恨所销蚀,抬起下巴,抓住今天,它不再回来。
结构体指针作为参数传递
函数中的参数列表本质上都是原来实参的副本,即下面代码中的root,指的是main函数中Troot的副本,由于是指针,所以副本和实参指向的都是同一个内存单元,如若只是改变副本所指内存单元的数据,那么实参内存所指的数据也同样被改变;但是由于在函数内部,改变了副本的内存单元,实参的内存单元并没有发生改变,所以实参的数据并没有跟着副本一起改变。
如果想改变实参的数据,那么应该传递结构体指针变量的指针或者其引用,1.第一种方式,结构体指针变量的指针本质上就是这个变量的地址,通过改变这个指针指向的内存单元的内容从而达到修改结构体指针的内容;2.第二种方式,结构体指针变量的引用其本质就是这个结构体变量的别名,对其引用所进行的操作本质上都是对其自身的操作
//创建二叉树
void CreatBitTree(BiTNode*& root)
void CreatBitTree(BiTNode** root)
void CreatBitTree(BiTNode* root)
{
int node;
cout << "请输入节点数据" << endl;
cin >> node;
if (node == -1)
root = nullptr;
else
{
root = new BiTNode;
if (root == nullptr)
{
cout << "error" << endl;
}
else
{
root->data = node;
CreatBitTree(root->lchild);
CreatBitTree(root->rchild);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
int main()
{
BiTNode *Troot=nullptr;
CreatBitTree(Troot);
}
- 1
- 2
- 3
- 4
- 5