请教,没有指定形参的函数,为啥可以传参?谢谢

oracleperl 2021-01-14 07:18:18
请教,如下程序可以编译执行,返回20,为啥函数f2没有形参,却可以传参?
f2 ()
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100));
return 0;
}
...全文
1276 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
oracleperl 2021-05-07
  • 打赏
  • 举报
回复
引用 23 楼 早打大打打核战争 的回复:
跟“编译器的漏洞”没关系,C的函数原型f()等于f(...),而C++的f()等于f(void),这是C和C++的重要区别之一
谢谢大神
  • 打赏
  • 举报
回复
跟“编译器的漏洞”没关系,C的函数原型f()等于f(...),而C++的f()等于f(void),这是C和C++的重要区别之一
flying_music 2021-05-06
  • 打赏
  • 举报
回复
有的编译器没检查,有的会检查,这么用肯定是不对的,所以可以理解为编译器的漏洞,不要这么用就可以了
5250 2021-05-06
  • 打赏
  • 举报
回复
引用 20 楼 oracleperl 的回复:
[quote=引用 9 楼 5250 的回复:]没有参数 默认是可以传递参数的 除非参数为void

谢谢大神, 那最多可以传几个参数呢?
谢谢[/quote]

内存角度来看,函数的参数是要入栈的,栈区大小决定了参数的个数。一般C语言程序运行时默认1M的栈空间,以int类型的参数来看,1M=1024KB=1024*1024字节,32位系统中int类型占4个字节,所以理论上一个函数最多有262144个int类型的参数。实际中要远远小于这个数,因为应用程序中的局部变量都需要占用栈空间。
oracleperl 2021-05-06
  • 打赏
  • 举报
回复
引用 9 楼 5250 的回复:
没有参数 默认是可以传递参数的 除非参数为void
谢谢大神, 那最多可以传几个参数呢? 谢谢
郑剑1996 2021-01-21
  • 打赏
  • 举报
回复
引用 7 楼 赵4老师 的回复:
不看编译器源代码,不看每句C/C++语句对应的汇编指令,你永远是“隔靴搔痒”。
__cdecl :C和C++缺省调用方式 例子: void Input( int &m,int &n); /*相当于void __cdecl Input(int &m,int &n);*/ 以下是相应的汇编代码: 00401068 lea eax,[ebp-8] ;取[ebp-8]地址(ebp-8),存到eax 0040106B push eax ;然后压栈 0040106C lea ecx,[ebp-4] ;取[ebp-4]地址(ebp-4),存到ecx 0040106F push ecx ;然后压栈 00401070 call @ILT+5(Input) (0040100a);然后调用Input函数 00401075 add esp,8 ;恢复栈 从以上调用Input函数的过程可以看出:在调用此函数之前,首先压栈ebp-8,然后压栈ebp-4,然后调用函数Input,最后Input函数调用结束后,利用esp+8恢复栈。由此可见,在C语言调用中默认的函数修饰_cdecl,由主调用函数进行参数压栈并且恢复堆栈。 https://blog.csdn.net/My_heart_/article/details/51520363 https://blog.csdn.net/luoweifu/article/details/52425733 能看明白吗?总之在_cdecl 调用方式中,由调用者来维护参数.如果被调用的函数没有使用任何参数,不对栈进行读取和操作.那么传递任何东西是无所谓的.但是其他调用约定就不行了.具体我没有实验,大体就是这么个事儿
5250 2021-01-20
  • 打赏
  • 举报
回复
引用 14 楼 oracleperl 的回复:
[quote=引用 9 楼 5250 的回复:]没有参数 默认是可以传递参数的 除非参数为void

f2 ()
{
return 20;
}

f1 (void)
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100)); //不会出错
printf("result is=%d\n",f1(100)); //出错
return 0;
}

谢谢大神,类似 f() 那么可以I传几个参数,参数的类型是什么?
[/quote]

自己写一个简单的程序看一下不就行了 几个参数 参数的类型你就试试呗
赵4老师 2021-01-20
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 你尤其要迷信你手头的这款编译器。毕竟县官不如现管。
oracleperl 2021-01-19
  • 打赏
  • 举报
回复
这样的写法可以传几个参数?每个参数的类型都是int?我查阅了一些书籍,没找到相关说明 int f() { return 0; }
oracleperl 2021-01-18
  • 打赏
  • 举报
回复
引用 9 楼 5250 的回复:
没有参数 默认是可以传递参数的 除非参数为void
f2 ()
{
return 20;
}

f1 (void)
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100)); //不会出错
printf("result is=%d\n",f1(100)); //出错
return 0;
} 
谢谢大神,类似 f() 那么可以I传几个参数,参数的类型是什么?
赵4老师 2021-01-15
  • 打赏
  • 举报
回复
引用 8 楼 oracleperl 的回复:
[quote=引用 7 楼 赵4老师 的回复:]不看编译器源代码,不看每句C/C++语句对应的汇编指令,你永远是“隔靴搔痒”。
谢谢赵老师提醒, 您说的编译器源码,C/C++语句对应的汇编指令,我在哪里看到? 感谢赵老师[/quote] 编译器源代码:初级Tiny C Compiler;终极gcc/g++ C/C++语句对应的汇编指令:Windows VS20xx,调试时打开汇编指令窗口;Linux g++,gdb调试时,layout asm
真相重于对错 2021-01-15
  • 打赏
  • 举报
回复
老编译器的毛病。。。。。。
5250 2021-01-15
  • 打赏
  • 举报
回复
没有参数 默认是可以传递参数的 除非参数为void

f2 ()
{
return 20;
}

f1 (void)
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100)); //不会出错
printf("result is=%d\n",f1(100)); //出错
return 0;
}

oracleperl 2021-01-15
  • 打赏
  • 举报
回复
引用 7 楼 赵4老师 的回复:
不看编译器源代码,不看每句C/C++语句对应的汇编指令,你永远是“隔靴搔痒”。
谢谢赵老师提醒, 您说的编译器源码,C/C++语句对应的汇编指令,我在哪里看到? 感谢赵老师
赵4老师 2021-01-15
  • 打赏
  • 举报
回复
不看编译器源代码,不看每句C/C++语句对应的汇编指令,你永远是“隔靴搔痒”。
oracleperl 2021-01-15
  • 打赏
  • 举报
回复
引用 5 楼 自信男孩 的回复:
[quote=引用 3 楼 oracleperl 的回复:][quote=引用 1 楼 自信男孩 的回复:]
c.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 f2 ()
 ^~
走的默认。如果楼主要明白诸如此类问题,可以读一下C标准,了解编译器编译的语法检查规则~
请教下什么默认?有书籍,文档说明吗?比如C标准? 哪里可以看到? 感谢[/quote] 感谢大神 默认的意思就是如果没有定义或者声明,按照int来处理~[/quote] 有书籍或者官方文档说明吗? 我看到K&R C那本书上说,不指定函数返回类型,那么默认int 但是对函数的参数,假设是 F() 没有说有几个参数,也没说默认是恩么类型 谢谢
5250 2021-01-15
  • 打赏
  • 举报
回复
引用 12 楼 oracleperl 的回复:
[quote=引用 9 楼 5250 的回复:]没有参数 默认是可以传递参数的 除非参数为void

f2 ()
{
return 20;
}

f1 (void)
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100)); //不会出错
printf("result is=%d\n",f1(100)); //出错
return 0;
}

可以I传几个参数?参数的数据类型是什么?
我仔细阅读了《C和指针》英文版,感觉对函数那一章的陈述,前言不搭后语,没有把概念说清楚
对于没有参数的函数,那本书上是说“假定是正确的”

对于什么是函数原型,更是没有说清楚。。
貌似
int f(int a);
这一行肯定就是函数原型
那么 如下代码的int f(int a) 算不算函数原型呢?
int f(int a)
{
return 1;
}
[/quote]

对于无参函数来说,参数是不确定的 你可以给它设置多个参数,多个类型 只要能在栈上放下 理论上都没有错误 但是不建议这样做 不安全。
int f(int a);//这里只是申明了函数,函数的原型即函数的定义   定义的函数要和函数的申明一致
int f(int a)
{
return 1;
} 这个就是函数的原型了



关于函数的申明和定义参考下面链接
https://blog.csdn.net/xingzhe22222/article/details/98870457
oracleperl 2021-01-15
  • 打赏
  • 举报
回复
引用 9 楼 5250 的回复:
没有参数 默认是可以传递参数的 除非参数为void
f2 ()
{
return 20;
}

f1 (void)
{
return 20;
}

int main()
{
printf("result is=%d\n",f2(100)); //不会出错
printf("result is=%d\n",f1(100)); //出错
return 0;
} 
可以I传几个参数?参数的数据类型是什么? 我仔细阅读了《C和指针》英文版,感觉对函数那一章的陈述,前言不搭后语,没有把概念说清楚 对于没有参数的函数,那本书上是说“假定是正确的” 对于什么是函数原型,更是没有说清楚。。 貌似 int f(int a); 这一行肯定就是函数原型 那么 如下代码的int f(int a) 算不算函数原型呢? int f(int a) { return 1; }
加载更多回复(5)

70,025

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧