c语言教学视频 结构体函数:PHP的语言结构和函数的区别

21:10 提问
C语言函数的形参(结构体类型)和实参类型(指针)可以不同吗?
void main()
char str[2];
pointer=(student *)malloc(lens*LEN); /分配内存*/
numstus=0;
welcome(); /*欢迎界面*/
while(i&0)
i=menu_select(); /*控制菜单*/
case 1:addrecord(pointer); /*增加学生信息*/
。。。省略
而当调用addrecord函数的定义是
void addrecord(student stud[]) {...}
pointer是个结构体指针
addrecord参数是 结构体类型
程序无错,传递可行
真是怎么回事
按赞数排序
代码不全。
是这样的,和参数无关,C语言存在类型的隐式转换,比如说一个short可以被当作一个int,而无需额外的转换,但是相反就不行。
隐式转换方便了开发者编码,但是它的限制同样为了防止你无心犯错。
好比你用大碗盛小碗的食物,编译器不用让你确认,自己就做了。但是你用小碗装大碗的食物,那么编译器提醒你,如果大碗的东西太多,可能会出错。那么你需要写清楚,表示你知道这么回事,它才接受。
请你附上所有代码,好吗?
就是,请附上代码,要不然没法解答
实参有类型
,形参空,可以进行传递,接收任何参数
实参有类型
,形参空,可以进行传递,接收任何参数
指针只是一个地址是一个数,类型只是告诉程序在这个地址上以何种方式去获得数据,如果方式不对获取的数据就是错误的,实参和形参可以类型不同,使用的时候需要强制转换。
数组在传递参数的时候自动变成指向数组头的指针,所以可以调用成功。采纳的答案说的虽然没错,但是和这个问题不符。
其他相似问题【哇哈哈哈】结构体里边可以定义函数!!!_c语言吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:510,203贴子:
【哇哈哈哈】结构体里边可以定义函数!!!收藏
//就是一个抽风的点子没想到真的可行,啊哈哈哈哈哈哈哈哈哈……//By Patricia.Xiao#include &stdio.h&#include &string.h&struct test{
int f(int x) {
int result=1;
if(x == a)
for(i=i&=i++)
result*=i;
}};int main(){
number.a = 1; //这里可以改成任何数也可以待输入
scanf("%d",&n); int result = number.f(n); printf("%d\n",result); //目前的作用是求阶乘……之类的。 return 0;}
票牛教你如何买到热门、便宜、真实的演出门票!
Yet Another GNU Extension?
有谁能解释一下GNU是啥么。百度了一下表示有看没有懂……
从某种意义上说,楼主的代码是C++代码,带-std=c++11编译不报错,不出警告……
[lhanjian@lhjins14d ~]$ clang++ /tmp/test.cclang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated不过clang++还是有警告,没报错……clang报错和GCC类似
c++结构体中可以定义函数貌似
这是C还是C++?c++是可以的
这样你只需要在主函数中调用变量
程序代码就封装在结构体当中了~~~~~
int main(){printf("%s\n", sizeof('0') == sizeof(int) ? "c":"c++");}
机票预订丨南航官网丨购票低至2折丨特价机票80元起!
我滚回来跪拜了。。。一直都只敢规规矩矩地写。。。
我还以为gcc方言连this都支持了,结果居然是.cc?
c不允许的吧 结构体成员为函数指针的话一定程度上还可以模拟
这好像是C++的写法吧...
爪机,没细看。如此一说,结构体中定义了一个函数,函数的形参又是这种类型的结构体,形参的结构体中又包含一个函数……循环定义,目测不靠谱
实话说开头来了点C++后面大部分C
楼主用.cpp来糊弄人的吧!
这样就好了
滚出来膜拜(#……)
GNU C引用C++的面向对象思想的扩展,在驱动程序里经常用到,不过是以函数指针的形式定义,例如:struct test{
(int *)f(int);}
楼主攒jy的能力真是一流,实在是佩服
个人以为,c++中的class 就是strut 的某种强化 -- 这个strut 基本有类的雏形了。。。一般情况下,gcc xxx.c 它会按照 c来编译如果gcc xxx.cc/xxx.cpp/etc 它就会默认按照c++来编译了所以,有理由猜测,LZ取名是xxx.cpp/xxx.cc/xxx.cx ?
man gcc 得到如下描述:For any given input file, the file name suffix determines what kind of compilation is done:
C source code that must be preprocessed.。。。。file.cc
C++ source code that must be preprocessed.
Note that in .cxx, the last two letters must both be literally x.
Likewise, .C refers to a literal capital C.@Laconism如上我记得有这么段来着而且,gcc还可以编译.m,.mm 甚至是.go不过它其实是调用机器中的其他编译程序而已
//Patricia.Xiao#include &stdio.h&#include &stdlib.h&typedef struct A{ void (*func)();} A;voidA_func(){ printf("Hello World.\n");}A*new_A(){ A * to_ret = (A *) malloc(sizeof(A)); to_ret-&func = A_ //to_ret-&func();
//debug//bug:忘写括号() return to_}int main(){ A * testing= new_A(); testing-&func(); return 0;}//话说这个是LZ至今为止码过的最牛气的hello world有木有!!!
进错吧了。
写c代码的时候最好别用.cpp后缀吧,有时候会出现某些问题。
楼主劝你直接投入c++的怀抱,明天开始到隔壁报告吧
clang默认带-std=gnu99。不过是弄成C++了吧。GNU扩展让你能在函数内定义函数。
C++的可以这样做 用c编译器处理这代码 直接
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或C语言结构体中的函数指针
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。所以,标准C中的结构体是不允许包含成员函数的,当然C++中的结构体对此进行了扩展。那么,我们在C语言的结构体中,只能通过定义函数指针的方式,用函数指针指向相应函数,以此达到调用函数的目的。
1. 函数指针
一般的函数指针可以这么定义:
int(*func)(int,int);
表示一个指向含有两个int参数并且返回值是int形式的任何一个函数指针. 假如存在这样的一个函数:
int add2(int x,int y)
return x+y;
那么在实际使用指针func时可以这样实现:
func=&add2; //指针赋值,或者func=add2;
add2与&add2意义相同
printf("func(3,4)=%d"n",func(3,4));
事实上,为了代码的移植考虑,一般使用typedef定义函数指针类型.
typedef int(*FUN)(int,int);
FUN func=&add2;
2.结构体中包含函数指针
其实在结构体中,也可以像一般变量一样,包含函数指针变量.下面是一种简单的实现.
#include "stdio.h"
struct DEMO
int (*func)(int,int); //函数指针
int add2(int x,int y)
return x+y;
void main()
struct DEMO
demo.func=&add2; //结构体函数指针赋值
printf("func(3,4)=%d"n",demo.func(3,4));
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。千里之行 始于足下精诚所至 金石为开
欢迎加入我们,一同切磋技术。 &
用户名: &&&
密 码: &
共有 2223 人关注过本帖
标题:加下横线的函数名或者结构体和不加下横线的有什么区别呢?
等 级:侠之大者
帖 子:2168
专家分:425
结帖率:79.83%
&&已结贴√
&&问题点数:10&&回复次数:6&&&
加下横线的函数名或者结构体和不加下横线的有什么区别呢?
发现C语言中很多函数重复定义了两套,一个是有下横线的,一个是没有的,比如
函数:_fstat和 fstat
结构体:struct _stat和struct&&stat
而且他们的功能完全一样的,不知道这样弄的好处是什么?为什么有两个版本呢
搜索更多相关主题的帖子:
等 级:论坛游民
帖 子:45
专家分:16
这些都是用户标识符,标识符不一样功能也不一样
来 自:火星
等 级:贵宾
威 望:49
帖 子:1279
专家分:2732
移植 封装 扩充 简化。。。
小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
等 级:侠之大者
帖 子:2168
专家分:425
您可以在sys/stat.h 中看到这两个结构体被一模一样的写了两遍,而不是typedef或者define
以下是引用你们都要疼我哦在 03:24:45的发言:
移植 封装 扩充 简化。。。
define#ifndef _STAT_DEFINED
struct _stat {
&&&&&&&&_dev_t st_
&&&&&&&&_ino_t st_
&&&&&&&&unsigned short st_
&&&&&&&&short st_
&&&&&&&&short st_
&&&&&&&&short st_
&&&&&&&&_dev_t st_
&&&&&&&&_off_t st_
&&&&&&&&time_t st_
&&&&&&&&time_t st_
&&&&&&&&time_t st_
&&&&&&&&};
#if&&&&&!__STDC__
/* Non-ANSI names for compatibility */
struct stat {
&&&&&&&&_dev_t st_
&&&&&&&&_ino_t st_
&&&&&&&&unsigned short st_
&&&&&&&&short st_
&&&&&&&&short st_
&&&&&&&&short st_
&&&&&&&&_dev_t st_
&&&&&&&&_off_t st_
&&&&&&&&time_t st_
&&&&&&&&time_t st_
&&&&&&&&time_t st_
&&&&&&&&};
#endif&&/* __STDC__ */
~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
来 自:火星
等 级:贵宾
威 望:49
帖 子:1279
专家分:2732
移植 封装 扩充 简化。。。
只是举个例子,为了达到移植 封装 扩充 简化。。。这些目的,头文件中
用很多方式。
你怎么不去仔细看看定义前面那预处理预编译命令呢
小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
等 级:业余侠客
帖 子:353
专家分:222
看一下预定义能清楚啥意思
#ifndef _STAT_DEFINED 如果没有定义_stat
#if&&&&&!__STDC__&&如果不是标准c
说明如果是标准c里面就有stat这个结构,那么我就定义成_stat
而如果不是标准c本身就没有stat这个结构,那么我就定义成stat
等 级:侠之大者
帖 子:2168
专家分:425
关键是结构一样,为什么不用typedef呢?
~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
版权所有,并保留所有权利。
Powered by , Processed in 0.019421 second(s), 8 queries.
Copyright&, BCCN.NET, All Rights ReservedC语言中结构体在函数中的应用
前天在编写一段代码时突然对结构体在函数中的用法有些模糊了,经过复习,基本弄清了这些知识,特总结如下:
一、结构体与函数参数
结构体作函数参数可分为传值与传指针。
1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数。在这种情况下,由于涉及到结构体参数的拷贝,程序空间及时间效率都会受到影响,所以这种方法基本不用。
typedef struct tagSTUDENT{
char name[20];
void fun(STUDENT stu)
printf(“stu.name=%s,stu.age=%d/n”,stu.name,stu.age);
2.传指针时直接将结构体的首地址传递给函数体,在函数体中通过指针引用结构体成员,可以对结构体参数成员的值造成实际影响。这种用法效率高,经常采用。
typedef struct tagSTUDENT{
char name[20];
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];
STUDENT fun();
int _tmain(int argc, _TCHAR* argv[])
STUDENT p=fun();
printf("p.name=%s",p.name);
STUDENT fun()
stu.age=18;
strcpy(stu.name,"xiaoming");
以指针方式返回结构体示例如下:
typedef struct tagSTUDENT{
char name[20];
STUDENT* fun()
STUDENT* p=malloc(sizeof(STUDENT));
p-&age=18;
strcpy(p-&name,"xiaoming");
关于结构体,看内核又遇到了,关于赋值中存在·的奇怪用法,在网上没有找到答案,却把以前一直弄的比较模糊的对齐问题给翻出来了。如下为转发内容:
有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#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{
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&
sizeof(A) = 6; 这个很好理解,三个short都为2。
sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。
例2:struct A{
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。
深究一下,为什么是这样,我们可以看看内存里的布局情况。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
A的内存布局:1111,&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
b&&&&&&&&&
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{
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
char e[2];
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
sizeof(A) = 24;
这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
sizeof(B) = 48; 看看B的内存布局。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
f&&&&&&&&&&&&
g&&&&&&&&&&&&&&&
h&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
B的内存布局:11* *,&&
1111* * * *, 11 * * * *
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&&&&&&&&&&&&
A的内存布局:1111,&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
f&&&&&&&&&&&&
g&&&&&&&&&
h&&&&&&&&&&&&&&&&&&&&
B的内存布局:11,&&
,&&&&&&&&&&&
那#pragma pack(2)的结果又是多少呢?#pragma pack(4)呢?留给大家自己思考吧,相信没有问题。
还有一种常见的情况,结构体中含位域字段。位域成员不能单独被取sizeof值。C99规定int、unsigned
int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。
使用位域的主要目的是压缩存储,其大致规则为:&
如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;&
如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;&
如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;&
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;&
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
还是让我们来看看例子。
例4:struct A{&
&&&&&&&&&&&&&&&&&&&&&
char f1 : 3;&
&&&&&&&&&&&&&&&&&&&&
char f2 : 4;&
&&&&&&&&&&&&&&&&&&&&
char f3 : 5;&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
b&&&&&&&&&&&&
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 f3 : 5;&
&&&&&&&&&&&&&&&&&&&
非位域字段穿插在其中,不会产生压缩,在VC6和Dev-C++中得到的大小均为3。
考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。
最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 c语言入门 的文章

 

随机推荐