C语言结构体指针_C语言函数返回结构体指针

C语言结构体指针_C语言函数返回结构体指针文章目录结构体概述结构体指针结构体概述问题定义:有时需要将不同类型的数据组合成一个有机的整体,以便于使用,就类似于sql中的存储一样,随着语言层次的增高封装性是越来越大的。如:intnum;charname[20];charsex;intage;charaddr[30];定义结构的一般形式为:struct结构名{成员列表};成员列表由若干个成员构成,每个成员…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

结构体概述

问题定义:有时需要将不同类型的数据组合成一个有机的整体,以便于使用,就类似于sql中的存储一样,随着语言层次的增高封装性是越来越大的。如:

int num;
char name[20];
char sex;
int age;
char addr[30];

Jetbrains全家桶1年46,售后保障稳定

在这里插入图片描述
定义结构的一般形式为:
struct 结构名{

成员列表
};

成员列表由若干个成员构成,每个成员都是该结构的组成部分,对每个成员必须做类型说明,其形式为:
类型说明符 成员名;
例如说

struct student{ 
   
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
}

可以采用以下三种方法定义结构体类型变量:

  • (1)先声明结构体类型再定义变量名
    例如:struct(类型名) student(结构体) student1(变量名),student2(变量名);
    定义了student1和student2为struct student类型的变量,即他们具有struct student类型的结构

  • (2)在声明类型的同时定义变量这种形式的定义的一般形式为:
    struct 结构体名{

    成员列表
    }变量名;
    例如:

struct student{ 
   
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
}student1,student2

在定义了结构体变量后,系统会为其分配内存单元。例如:
student1和student2在内存中各占几字节?
答(4+20+1+4+4+30 = 63)

  • (3)直接定义结构体类型变量其一般形式为:
    struct{

    成员列表
    }变量名

现在我们直到了怎么构造一个结构体了,下面要说一下在结构体内引用另一个结构体的方法,也就是在结构体内嵌套另一个结构体
在这里插入图片描述
首先我们定义一个结构体date,由month,day,year组成
在定义说明变量boy1和boy2时,其中的成员birthday被说明为date结构类型。成员名可与程序中其他变量同名,互不干扰。

struct date{ 
   
	int month;
	int day;
	int year;
};
struct { 
   
	int num;
	char name[30];
	char sex;
	struct date birthday;
	float score;
}boy1,boy2;

引用变量法则:
(1)不能将一个结构体变量作为一个整体进行输入和输出。
应该这样引用:

int main() { 
   
    boy1.num = 01;
    boy1.sex = 'M';
    printf("%d,%c", boy1.num, boy1.sex);
}

对于结构体的基础语法说完了,下面来说结构体指针

结构体指针

一个结构体变量的指针就是该结构体变量所占据内存段的起始地址。
可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
同时指针变量也可以用来指向结构体数组中的元素。
结构体指针变量说明的一般形式为:
struct 结构名 *结构指针变量名
例如,在前面的例题中定义了stu这个结构,如果要说明一个指向stu的指针变量pstu,可写为

struct stu *pstu;

当然也可以在定义stu结构时同时说明pstu。与前面讨论的各类指针变量相同,结构体指针变量也必须要先赋值才能使用
赋值就是把结构变量首地址赋予该指针变量,不能把结构名赋予该指针变量。
如果boy是被说明为stu类型的结构变量,则:
pstu = &boy;是正确的
pstu = &stu;是错误的
因为结构名和结构变量是两个不同的概念,不能混淆。结构名只能表示一个结构形式,编译系统并不对他们分配内存空间,只有当某变量被说明为这种类型的结构时,才对该变量存储内存空间。
所以以上 pstu = &stu;是错误的,不可能去取一个结构名的首地址。有了结构指针变量,就更方便地访问结构变量的各个成员。
其访问的一般形式为:
(*结构指针变量).成员名
或为:
结构指针变量->成员名
例如:(*pstu).num
或者:pstu->num

小案例

struct stu{ 
   
    int num;
    char *name;
    char sex;
    float score;
}boy1 = { 
   006,"zhangzhang",'1',69.6};

int main() { 
   

    struct stu *pstu;
    pstu = &boy1;

    printf("%d,%s\n", boy1.num, boy1.name);

    printf("%d,%s\n", (*pstu).num, (*pstu).name);

    printf("%d,%s\n", pstu->num, pstu->name);

}

例题:有一个结构体变量stu,内含学生学号、姓名和三门学科的成绩,通过调用函数print使他们输出

struct student{ 
   
    int num;
    char *name;
    int score[3];
};
void print(struct student stu,struct student *pstu){ 
   

    printf("num:%d\n",stu.num);
    printf("name:%s\n", stu.name);
    printf("score[0]:%d\n", pstu->score[0]);
    printf("score[1]:%d\n", (*pstu).score[1]);
    printf("score[2]:%d\n", (*pstu).score[2]);
}
int main() { 
   
    struct student *p;
    struct student stu;

    stu.num = 007;
    p->name = "zhangzhang";
    (*p).score[0] = 59;
    (*p).score[1] = 60;
    (*p).score[2] = 61;

    print(stu,p);

// struct stu *pstu;
// pstu = &boy1;
//
// printf("%d,%s\n", boy1.num, boy1.name);
//
// printf("%d,%s\n", (*pstu).num, (*pstu).name);
//
// printf("%d,%s\n", pstu->num, pstu->name);



}

动态存储分配

在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。在C语言中不允许动态数组类型。例如:a[n]就是错误的,必须要用一个实际的数字表示数组长度,但是在实际开发中,往往会发生这种情况,即所需要的内存空间取决于实际输入的数据,而无法预先确定。对于以上问题,使用数组的办法很难解决,只能通过内存管理函数,动态分配内存空间。
常用的内存管理函数有以下三个:
1.分配内存空间函数malloc,calloc
2.释放内存空间函数free

<1>.malloc函数

函数原型为void *malloc(unsigned int size);
其作用是在内存的动态存储中分配一个长度为size的连续空间(size是一个无符号数)
此函数的返回值是一个指向分配域起始地址的指针(void)。
如果此函数未能成功地执行(例如内存空间不足),则返回Null.

<2>.calloc函数

函数原型是void *calloc (unsigned n,unsigned size)
其作用是在内存的存储区中分配n个长度为size的连续空间。
函数返回一个指向分配域起始地址的指针。
如果分配不成功,返回Null
用calloc函数可以为一维数组开辟动态存储空间,n为数组个数,每个元素长度为size

<3>.free函数

函数原型是void free(void *p)
其作用是释放由p指向的内存区,使这部分内存区能被其他区使用
p是最近一次调用calloc或者malloc函数的时候返回的值。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203524.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux下编译和安装log4cxx,ubuntu下log4cxx安装使用「建议收藏」

    linux下编译和安装log4cxx,ubuntu下log4cxx安装使用「建议收藏」需要安装log4cxx,安装的过程中可是充满了坎坷。。。最大的问题是在makelog4cxx时,总是报undefinedXML什么什么的错误,查了一下也没解决了,然后把apr-utils删了重新装了一下就好了。。log4cxx现在是apache的一个项目,用来记录日志。看名字就知道,是给c++使用的。环境(在以下2个环境中进行验证测试):gcc(Ubuntu4.8.4-2ubuntu1~1…

    2022年6月20日
    24
  • ECshop二次开发「建议收藏」

    ECshop二次开发「建议收藏」1.ECShop之更改商城楼层显示:ECShop原来楼层显示效果:根据现在的楼层需要添加新的一类楼层:①登录商城后台依次打开商品管理=》商品分类,此时对应模块的楼层如图所示:②编辑需要添加分类,将“在频道首页显示该二级分类”选项更改为显示:③刷新前端,对应页面的分类显示数据就显示出来了…

    2025年8月22日
    2
  • pycharm只能安装在c盘吗_pycharm自带python吗

    pycharm只能安装在c盘吗_pycharm自带python吗昨天大家对我(Python)有了一定的了解,那么今天带大家更加系统化的认识一下我,已经了解我的工作方式先说一下如果让我去做一件事情得需要那些“配置”,其实很简单的,不要把我想的太复杂,毕竟还是个单纯的孩子。让我做事当然是有一条一条简短的指令,汇聚在一起然后成为一个模块,之所谓”不积跬步无以至千里,不积小流无以成江海“,正确的指令汇聚在一起我们可以改变世界!咳咳:正经的说一边”1、python是由一…

    2022年8月27日
    1
  • javascript如何定义类

    javascript如何定义类

    2021年8月5日
    61
  • java最长递增子序列_求数组最长递增子序列

    java最长递增子序列_求数组最长递增子序列[java]代码库packagecom.wzs;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.List;//求数组中最长递增子序列publicclassTest{publicstaticvoidmain(String[]args){inta[]={1,-1,2,-3,4,-5,6…

    2022年5月2日
    58
  • 解读滑块验证码(滑动验证码)与图形验证码的破解难度

    解读滑块验证码(滑动验证码)与图形验证码的破解难度

    2021年6月7日
    129

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号