精华内容
下载资源
问答
  • 在下面代码中,编译过程中总是提示name, species, teeth, age这四个标识符未定义,但是在前面的结构体中不是已经定义了吗。这个该怎么办啊,小实在想不出来啦。 struct fish { const char *name; const ...
  • C语言结构体通过函数指针调用函数 (C语言结构体不能直接放函数,C++可以) #include<stdio.h> #include<stdlib.h> int j(int a)//平方 { int c; c = a * a; return c; } int s(int b)//三次方 { ...

    C语言结构体通过指针调用函数
    (C语言结构体不能直接放函数,C++可以)

    #include<stdio.h>
    #include<stdlib.h>
    int j(int a)//平方
    {
    	int c;
    	c = a * a;
    	return c;
    }
    int s(int b)//三次方
    {
    	int d;
    	d =b*b*b;
    	return d;
    }
    struct Str
    {
    	int(*p)(int b);//p为函数指针,若调用的函数没有参数则为(*p)();
    };
    
    
    void main()
    {
    	int b = 10;
    	struct Str str = { s };//初始化,传所调用的那个函数名或者在名字加&
    	
    	printf("%d", str.p(b));//.和()同级且从左往右计算
    }
    

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 接触嵌入式编程已经有一段时间了,平时的编程中会经常遇到结构体,但是就直接...注:关于结构体的三种形式,可以自己研究研究。 我实验的程序如下: #include struct stu { char name[20]; long number; float s

    接触嵌入式编程已经有一段时间了,平时的编程中会经常遇到结构体,但是就直接拿来用了,没有注意过细节,结果遇到问题就纠结了。趁这个机会,研究了一下C语言的结构体和结构体指针,顺便总结一下!

    注:关于结构体的三种形式,可以自己研究研究。

    我实验的程序如下:

    #include <stdio.h>
    
    struct stu
    {
        char name[20];
        long number;
        float score[4];
    };
    struct data
    {
        int day;
        int month;
        int year;
    };
    
    int add(struct stu *ss1, struct stu *ss2)
    {
    	return ss1->number+ss2->number;
    }
    
    int main()
    {
        struct stu *s3,*s4,s5,s6;
    	//s3 = malloc(sizeof(struct stu));
    	//s4 = malloc(sizeof(struct stu));
    	s3 = &s5;
    	s4 = &s6;
        s3->number = 1;
    	s4->number = 2;
    	s5.number = 3;
        printf("%d\n",s3->number);
    	printf("%d\n",s4->number);
    	printf("%d\n",s5.number);
    	printf("%d\n",add(s3,&s5));
    	printf("%d\n",sizeof(struct stu));
        return 0;
    }
    
    注意到一下几点:

    1.定义结构体指针后,一定要给它分配空间,有两种方式,一种死malloc,另一种是用一个结构体变量的地址给他赋值。

    2.通过结构体指针访问接头体成员,用->;通过结构体变量访问成员,用.;并且优先级:.高于*。

    3.作为函数参数时,要分清指针还是变量。要是指针就直接传入,要是变量就取地址&。


    展开全文
  • 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员值实际上是修改调用参数一个临时拷贝成员值,这不会影响到调用参数。在这种情况下,由于涉及到结构体参数拷贝,程序空间及时间效率都会受...

    一、结构体与函数参数

    结构体作函数参数可分为传值与传指针。

    1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数。在这种情况下,由于涉及到结构体参数的拷贝,程序空间及时间效率都会受到影响,所以这种方法基本不用。

    例如:

    typedef struct tagSTUDENT{

    char name[20];

    int age;

    }STUDENT;

    void fun(STUDENT stu)

    {

    printf(“stu.name=%s,stu.age=%d/n”,stu.name,stu.age);

    }

    2.传指针时直接将结构体的首地址传递给函数体,在函数体中通过指针引用结构体成员,可以对结构体参数成员的值造成实际影响。这种用法效率高,经常采用。

    例如:

    typedef struct tagSTUDENT{

    char name[20];

    int age;

    }STUDENT;

    void fun(STUDENT* pStu)

    {

    printf(“pStu->name=%s,pStu->age=%d/n”,pStu->name,pStu->age);

    }

    二、结构体与函数返回值

    对于某些版本的C语言编译器,返回值仅能为基本数据类型如int、char以及指针,因此结构体作为一种组合数据类型,不能以值的方式返回,而在有些版本的C编译器中又可以直接返回结构体变量

    ,在C++中也是可以直接返回结构体变量的。

    直接返回结构体变量示例如下;

    typedef struct tagSTUDENT{

    char name[20];

    int age;

    }STUDENT;

    STUDENT fun();

    int _tmain(int argc, _TCHAR* argv[])

    {

    STUDENT p=fun();

    printf("p.name=%s",p.name);

    return 0;

    }

    STUDENT fun()

    {

    STUDENT stu;

    stu.age=18;

    strcpy(stu.name,"xiaoming");

    return stu;

    }

    以指针方式返回结构体示例如下:

    typedef struct tagSTUDENT{

    char name[20];

    int age;

    }STUDENT;

    STUDENT* fun()

    {

    STUDENT* p=malloc(sizeof(STUDENT));

    p->age=18;

    strcpy(p->name,"xiaoming");

    return p;

    }

    关于结构体,看内核又遇到了,关于赋值中存在·的奇怪用法,在网上没有找到答案,却把以前一直弄的比较模糊的对齐问题给翻出来了。如下为转发内容:

    有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下):

    原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

    原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct

    a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

    原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。

    这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。

    例1:struct{

    short a1;

    short a2;

    short a3;

    }A;

    struct{

    long a1;

    short a2;

    }B;

    sizeof(A) = 6; 这个很好理解,三个short都为2。

    sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。

    例2:struct A{

    int a;

    char b;

    short c;

    };

    struct B{

    char b;

    int a;

    short c;

    };

    sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。

    sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。

    深究一下,为什么是这样,我们可以看看内存里的布局情况。

    a b c

    A的内存布局:1111, 1*, 11

    b a c

    B的内存布局:1***, 1111, 11**

    其中星号*表示填充的字节。A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。

    B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。

    再看一个结构中含有结构成员的例子:

    例3:struct A{

    int a;

    double b;

    float c;

    };

    struct B{

    char e[2];

    int f;

    double g; short h;

    struct A i;

    };

    sizeof(A) = 24;

    这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。

    sizeof(B) = 48; 看看B的内存布局。

    e f g h i B的内存布局:11* *, 1111, 11111111, 11 * * * * *

    *, 1111* * * *, 11111111, 1111 * * * *

    i其实就是A的内存布局。i的起始位置要为24的倍数,所以h后面要补齐。把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。

    以上讲的都是没有#pragma pack宏的情况,如果有#pragma

    pack宏,对齐方式按照宏的定义来。比如上面的结构体前加#pragma pack(1),内存的布局就会完全改变。sizeof(A) =

    16; sizeof(B) = 32;

    有了#pragma pack(1),内存不会再遵循原则1和原则3了,按1字节对齐。没错,这不是理想中的没有内存对齐的世界吗。

    a b c

    A的内存布局:1111, 11111111, 1111

    e f g h i B的内存布局:11, 1111, 11111111, 11

    , 1111, 11111111, 1111

    那#pragma pack(2)的结果又是多少呢?#pragma pack(4)呢?留给大家自己思考吧,相信没有问题。

    还有一种常见的情况,结构体中含位域字段。位域成员不能单独被取sizeof值。C99规定int、unsigned

    int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。

    使用位域的主要目的是压缩存储,其大致规则为: 1)

    如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止; 2)

    如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍; 3)

    如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式; 4) 如果位域字段之间穿插着非位域字段,则不进行压缩; 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

    还是让我们来看看例子。

    例4:struct A{ char f1 : 3; char f2 : 4; char f3 : 5; };

    a b c

    A的内存布局:111, 1111 *, 11111 * * *

    位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只能从下一个字节开始。因此sizeof(A)的结果为2。

    例5:struct B{ char f1 : 3; short f2 : 4; char f3 : 5; };

    由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。

    例6:struct C{ char f1 : 3; char f2; char f3 : 5; };

    非位域字段穿插在其中,不会产生压缩,在VC6和Dev-C++中得到的大小均为3。

    考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。

    最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间

    展开全文
  • C语言 结构体

    2019-10-31 10:39:43
    结构体 ================================================================ 结构体是C语言的一种数据类型,和基本...结构体的内容在内存中是如何分配的? 首先判断结构体中的数据类型最大占多少字节: 例如最大为1...

    结构体

    ================================================================
    结构体是C语言的一种数据类型,和基本数据类型一样。结构体可以将不同类型的数据封装成一个集合方便我们进行调用。它本身不占据系统空间,只有在定义变量的时候才分配系统空间。

    结构体的内容在内存中是如何分配的?
    • 首先判断结构体中的数据类型最大占多少字节:
    • 例如最大为1个字节时(char):则按一字节对齐;
    • 最大为2字节时(short):则按2字节对齐;
    • 最大为4字节或以上的(int):则按4字节对齐 (32位机)。另外long在32位机中不是8字节而是4字节。
    • 最大位8字节或以上的(long):则按8字节对齐(64位机)。
    • 16位IBM-PC按一字节对齐,int为2字节。
    如何对齐呢?
    • 因为结构体在内存分配空间是连续的,假如为4字节对齐时,char类型也分配4个字节,剩余的3个字节则看下一个类型是否刚好放下,如果放不下则另外分配空间。
    • 指针类型不用看它所指向的内容是什么类型,一律看作4字节(32位)或8字节(64位)。

    ================================================================

    应用

    1.设计一个时间结构体,从系统获取时间并且初始化
    #include <stdio.h>  
    #include <time.h>
    
    //设计一个时间结构体,从系统获取时间并初始化。
    int main(int argc, char const *argv[])
    {
        struct _time{
        
            int year;
            int mon;
            int day;
            int hour;
            int min;
            int sec;
        };
    
        struct _time my_time;
    
        //获取时间间距
        time_t timep = time(&timep);
    
        //将时间间距转换为时间结构体
        struct tm sys_time = *(gmtime(&timep)); 
    
        //初始化自定义结构体
        my_time.year = sys_time.tm_year + 1900 ;
        my_time.mon = sys_time.tm_mon + 1 ;
        my_time.day = sys_time.tm_mday;
        my_time.hour = sys_time.tm_hour + 8 ;
        my_time.min = sys_time.tm_min;
        my_time.sec = sys_time.tm_sec;
    
        //显示时间
        printf("系统时间为: %d-%02d-%02d\t%02d:%02d:%02d\n", my_time.year,
                            my_time.mon, my_time.day, my_time.hour,
                            my_time.min, my_time.sec);
        //printf("%s\n", ctime(&timep));              
    
        return 0 ;
    }
    
    
    2.结构体空间大小计算:
    struct Data{
    	int *a;
    	char *b[10];
    	float c;  
    	void (*fun[5])(int);   
    	int (*d)[10];  
    	char e[4];  
    };
    

    32位编译系统: 4+40+4+20+4+4 = 76
    64位编译系统: 8+80+8+40+8+8 = 152
    关于类型占几个字节 16位 32位 64位都不一样
    https://blog.csdn.net/sifanlook/article/details/71419858

    展开全文
  • 最近在学习链表时,遇到结构体重复调用的情况。 链表首先声明一个节点结构体变量,如下: /*链表节点结构体*/ typedef struct ListNode { /*节点数据*/ int Element; /*节点指针,用来指向下一个节点*/ ...
  • 那么,我们在C语言的结构体中,只能通过定义函数指针方式,用函数指针指向相应函数,以此达到调用函数目的。 函数指针 函数类型 (*指针变量名)(形参列表);第一个括号一定不能少。 “函数类型”说明函数返回...
  • C语言结构体函数指针 结构体是由一系列具有相同类型或不同类型数据构成数据集合。所以,标准C中结构体是不允许包含成员函数,当然C++中结构体对此进行了扩展。那么,我们在C语言结构体中,只能...
  • C语言结构体

    2018-09-25 22:19:31
    前言 本博文基于VC++6.0开发调试运行; 本博文知识对结构体的一个简介; ...一般的变量定义都是独立的,变量与变量之间或许有联系,比如记录一个人的个人信息(身高,体重,年龄等)...结构体的功能就是做这个工作...
  • 本资源是针对C语言初学者期末课题设计,采用C语言编写一个小程序,通过循环、选择、调用等一系列C语言基础语句,实现了一段踢足球小动画,代码简单易懂,运行效果良好,供大家学习与参考
  • C语言_函数结构体的调用

    万次阅读 2019-04-06 00:40:05
    C语言_函数结构体的调用 #include<stdio.h> //定义存储函数的结构体 struct map{ //定义无参数类型返回void的函数指针 void (*p)(); }; /* * 通过实验观察系统如何处理整数上溢,浮点数上溢和浮点数下溢 ...
  • C语言结构体求矩形周长和面积

    千次阅读 2020-09-06 17:32:49
    ** C语言结构体求矩形周长和面积 ** 代码如下图: 运行结果如下: 总结: 要想将这道题做出来必须掌握结构体的基本结构定义,对结构体变量的初始化还有基本函数的调用
  • C语言结构体专题

    2020-10-31 09:18:34
    结构体变量引用 . 结构体变量指针 -> 02、结构体做函数参数 结构体赋值编译器行为研究 结构体变量做函数参数 PK 结构体指针做函数参数 结构体做函数参数(//结构体赋值和实参形参赋值行为研究) 内存四区调用...
  • 有关结构体的定义和使用: 1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年的问题。 代码内容: #include<stdio.h> /struct Date//放在这儿和放在main里边都可以,放在main之前...
  • Linux C语言结构体-学习笔记

    千次阅读 多人点赞 2018-07-22 13:02:31
    Linux C语言结构体简介 前面学习了c语言基本语法特性,本节进行更深入学习。 预处理程序。 编译指令: 预处理, 宏定义, 建立自己数据类型:结构体,联合体,动态数据结构 c语言表达式工具 逻辑运算符: &...
  • JNA—模拟C语言结构体

    千次阅读 2015-11-28 10:59:57
    不写怎样模拟C语言结构体,就不能算是真正解决了调用动态链接库问题。 C语言结构体用得实在是太广泛了。     首先说明一点,本文中大量把模拟Struct类写作为接口内部类。 这不是JNA
  • 如果用Labview调用C编写结构时,很重要。对学习C中结构体存储有很大帮助。
  • C语言结构体数组实例

    千次阅读 2019-08-23 20:15:34
    可以根据需求自己判断,并调用相应函数,实现想要功能。 比如:根据不同名字判断,去告诉我想要对每个人说话。 #include <stdio.h> //函数声明 int zhao_f(char *subject, int time); int zhou_f...
  • C/C++结构体知识点梳理1 结构体基本概念1.1 结构体的定义、创建与初始化CC++1.2 结构体的初始化,调用C2 实例:二叉树的生成与遍历P.S.:结构体变量存储详情 1 结构体基本概念 1.1 结构体的定义、创建与初始化 C 一、...
  •   深入解析JNA—模拟C语言结构体 前言 前几天写《JNA--JNI终结者》一文介绍JNA框架。写完之后才发现,忘了写比较有难度C语言...不写怎样模拟C语言结构体,就不能算是真正解决了调用动态链接库问题。 C语
  • Linux C语言结构体简介 前面学习了c语言基本语法特性,本节进行更深入学习。 预处理程序。 编译指令: 预处理, 宏定义, 建立自己数据类型:结构体,联合体,动态数据结构 c语言表达式工具 逻辑运算符: &...
  • C语言结构体和函数。

    2021-06-14 10:45:16
    建立一个单链表函数,该表元素包含学号,姓名和一门课成绩,写一个按学号查成绩函数,...它先调用建立函数,再调用查询函数,显示学生姓名和成绩。</p>
  • struct Student { char name[10]; int age; char sex[10];...使用不用typedef 的结构体时,创建一个结构体实例时候命名规则: ...每次创建一个结构体实例时候就必须调用struct Student A来操作;
  • 学生信息管理系统(C语言结构体版) 学生信息管理系统每个c语言入门者所需掌握一个操作系统模板。下面就简单来介绍一个该操作系统。 功能介绍 该系统所具备一般增、删、查、改。另外,可根据个人需要增加...
  • C语言结构体及函数传递数组參数演示样例 注:makeSphere()函数返回Sphere结构体,main函数中。调用makeSphere()函数,传递第一个參数为数组,传递数组作为指针。 ...
  • 在软件开发中,经常会遇到对字符串,内存比较处理,我们通常很少会自己手写一遍比较函数,会调用C语言库函数进行处理,如strcmp,strncmp,memcmp等。 面试时候,面试官经常会问过类似这样一个题目,这个题目考...
  • 我定义了一个结构体数组,然后题目要求按选择法把结构体内的数据从小到大...后来我把指针变量还为普通的结构体变量,就是把*temp改成了temp(相应的调用时的->改成了.),结果这样运行就没问题了,请教大佬这是为什么

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,046
精华内容 418
关键字:

c语言结构体的调用

c语言 订阅