社区
C语言
帖子详情
一个初学者的问题
Cnwanglin
2007-01-17 12:32:25
#include <stdio.h>
void main()
{
printf("hello world\n");
return;
}
请问大家,不定参数是在底层怎么实现的
函数返回为什么要用return ; 而不是花括号结束
...全文
235
7
打赏
收藏
一个初学者的问题
#include void main() { printf("hello world\n"); return; } 请问大家,不定参数是在底层怎么实现的 函数返回为什么要用return ; 而不是花括号结束
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
daly888
2007-01-17
打赏
举报
回复
printf的源代码
不定参数,函数声明用...
int printf (
const char *format,
...
)
/*
* stdout 'PRINT', 'F'ormatted
*/
{
va_list arglist;
int buffing;
int retval;
va_start(arglist, format);
_ASSERTE(format != NULL);
_lock_str2(1, stdout);
buffing = _stbuf(stdout);
retval = _output(stdout,format,arglist);
_ftbuf(buffing, stdout);
_unlock_str2(1, stdout);
return(retval);
}
Cnwanglin
2007-01-17
打赏
举报
回复
为什么要用 # 来表示预编译 #include 是什么意思
这个指令是怎么在编译原理里实现的
如何来区分其他可能造成混淆的情况
Cnwanglin
2007-01-17
打赏
举报
回复
还有,return 这个关键字在底层是怎么实现的
Cnwanglin
2007-01-17
打赏
举报
回复
参数列表里的三个点 ...
在编译系统里是怎么区分的,也要压入栈么
pluton
2007-01-17
打赏
举报
回复
#include <stdio.h>
#include <stdlib.h>
void myprintf(char* format, ...)
{
char* pArg=NULL,*p;
char c;
pArg = (char*) &format; //取得栈中变量的首地址
pArg += sizeof(format);
while (*format != '\0')
{
c =*format;
if (c != '%')
{
putchar(c); //照原样输出字符
}
else
{ //按格式字符输出数据
switch(*++format)
{
case 'd':
printf("%d",*((int*)pArg));
pArg += sizeof(int);
break;
case 'x':
printf("%#x",*((int*)pArg));
pArg += sizeof(int);
break;
case 'c':
putchar(*(char*)pArg);
pArg += sizeof(char);
break;
case 's':
{
int t ;
t = (int)*(int *)pArg;
char *p=(char *)t;
while(*p!='\0')
putchar(*p++);
pArg += sizeof(char*);
break;
}
case 'f': //输出浮点数
{
double g = *(double*)pArg; //浮点型以为double入栈
printf("%f",g);
pArg += sizeof(double);
break;
}
default:
pArg += sizeof(int);
break;
}
}
format++;
}
pArg = NULL;
return;
}
int main(int argc, char* argv[])
{
char *p="abcdefg";
int i=55;
double g=3.25;
myprintf("%f\n",g);
myprintf("%d\n",i); //输出int
myprintf("%s\n",p); //输出字符串
myprintf("%c\n",'t'); //输出字符
myprintf("%f %s %d %c\n",g,p,i,'o');
return 0;
}
pluton
2007-01-17
打赏
举报
回复
va_start,va_arg,va_end是在stdarg.h中被定义成宏的
func( Type para1, Type para2, Type para3, ... )
{
/****** Step 1 ******/
va_list ap;
va_start( ap, para3 ); //一定要“...”之前的那个参数
/****** Step 2 ******/
//此时ap指向第一个可变参数
//调用va_arg取得里面的值
Type xx = va_arg( ap, Type );
//Type一定要相同,如:
//char *p = va_arg( ap, char *);
//int i = va_arg( ap, int );
//如果有多个参数继续调用va_arg
/****** Step 3 ******/
va_end(ap); //For robust!
}
◎研究:
typedef char * va_list;
#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )
va_list argptr;
C语言的函数是从右向左压入堆栈的,调用va_start后,
按定义的宏运算,_ADDRESSOF得到v所在的地址,然后这个
地址加上v的大小,则使ap指向第一个可变参数如图:
栈底 高地址
| .......
| 函数返回地址
| .......
| 函数最后一个参数
| ....
| 函数第一个可变参数 <--va_start后ap指向
| 函数最后一个固定参数
| 函数第一个固定参数
栈顶 低地址
然后,用va_arg()取得类型t的可变参数值, 先是让ap指向下一个参数:
ap += _INTSIZEOF(t),然后在减去_INTSIZEOF(t),使得表达式结果为
ap之前的值,即当前需要得到的参数的地址,强制转换成指向此参数的
类型的指针,然后用*取值
最后,用va_end(ap),给ap初始化,保持健壮性。
Cnwanglin
2007-01-17
打赏
举报
回复
var_start 是怎么实现的,参数怎么传递的
java五子棋游戏 界面非常美观 有详细的注释 非常适合
初学者
总之,这个Java五子棋游戏项目涵盖了Java GUI编程、数据结构、算法设计、事件处理和多线程等多个重要知识点,对于想要学习Java编程和游戏开发的
初学者
来说,无疑是
一个
很好的实践项目。通过分析和理解这个游戏的源...
你必须知道的261个Java语言
问题
梁建全.pdf
书中不仅对每
一个
问题
提供了详细的解答,还结合了代码示例来阐明技术要点,使得理论与实践相结合,增强了学习的效果。 这本书的结构清晰,讲解透彻,实用性强,适合作为高校相关专业的Java语言课程的教学参考书,...
Android开发入门60个小案例+源代码
总之,"Android开发入门60个小案例+源代码"是
一个
宝贵的资源,它涵盖了Android开发的众多基础知识点,通过实践这些小案例,
初学者
可以快速上手,逐步掌握Android应用开发的核心技术。同时,源代码提供了直接参考和...
JAVA经典算法90题【含源码】
"JAVA经典算法90题【含源码】"的资源集合为Java
初学者
提供了
一个
绝佳的学习平台,旨在通过实际操作来理解和应用各种基础及进阶算法。下面将详细阐述这些算法题目所涉及的知识点,并建议的学习路径。 首先,"JAVA...
Dubbo入门实例Demo
【Dubbo入门实例Demo】是针对
初学者
设计的
一个
实践教程,旨在帮助新手快速理解并掌握Apache Dubbo这一高性能、轻量级的Java RPC框架。在学习过程中,新手往往会在配置、依赖、通信等方面遇到诸多
问题
,这个Demo就是...
C语言
70,026
社区成员
243,262
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章