void print(clstruct is voidaddress_list *head) 是什么意思

c语言中的void printlog(char *format,...)这是什么意思?_百度知道
c语言中的void printlog(char *format,...)这是什么意思?
我看别人源代码的时候,看到一个这种函数声明,参数列表中的...是什么意思呢?这是什么语法?我记得printf也是这么弄的:printf, (const char *, ...)
我有更好的答案
  表示printlog这个函数,接受任意多个参数,第一个参数必须为char&*类型,后面有多少个参数都可以,没有也可以。  C语言对可变参数的支持通过stdarg.h来实现,原理很简单。  首先让编译器识别...,允许函数调用传入任意数量的参数而不产生警告。然后在函数体里通过stdarg.h提供的几个宏来获取参数。  这是stdarg.h提供的用于实现变长参数的几个宏:#define&va_start(ap,v)&&&&&(&ap&=&(va_list)&v&+&_INTSIZEOF(v)&)#define&va_arg(ap,t)&&&&&&&(&*(t&*)((ap&+=&_INTSIZEOF(t))&-&_INTSIZEOF(t))&)#define&va_end(ap)&&&&&&&&&(&ap&=&(va_list)0&)  &va_start用来初始化,就是将指针指向栈中变长参数的起始位置。va_arg用来取参数,即将指针转换为指定类型的指针,取值。再将指针进行偏移。va_end用来完成清理工作,也就是把指针置为NULL。  例子:int&sum(unsigned&int&n,...)&&{&&&&&int&sum=0;&&&&&va_list&&&&&&va_start(args,n);&&&&&while(n&0)&&&&&{&&&&&&//通过va_arg(args,int)依次获取参数的值&&&&&&&&sum+=va_arg(args,int);&&&&&&&n--;&&&&&}&&&&&va_end(args);&&&&&return&&&}&&&&这段代码实现了对任意数量的整数的求和,整数的数目由n指定。所以说,变长参数的函数一定有一个已知类型的参数,即第一个参数,用来告知函数,一共传入了多少个参数,每个参数该取多长。
采纳率:56%
来自团队:
是可变参数,是c的一个语法现象,我在电脑上保存的一些资料,希望对你有用。一、什么是可变参数我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点&…&做参数占位符),实际调用时可以有以下的形式:
printf(&%d&,i);
printf(&%s&,s);
printf(&the number is %d ,string is:%s&, i, s);
以上这些东西已为大家所熟悉。但是究竟如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现,这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助.二、可变参数在编译器中的处理 我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的, 由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下面看一下VC++6.0中stdarg.h里的代码(文件的路径为VC安装目录下的\vc98\include\stdarg.h)
typedef char *
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v)
( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t)
( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap)
( ap = (va_list)0 )下面我们解释这些代码的含义:1、首先把va_list被定义成char*,这是因为在我们目前所用的PC机上,字符指针类型可以用来存储内存单元地址。而在有的机器上va_list是被定义成void*的2、定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统.这个宏的目的是为了得到最后一个固定参数的实际内存大小。在我的机器上直接用sizeof运算符来代替,对程序的运行结构也没有影响。(后文将看到我自己的实现)。3、va_start的定义为 &v+_INTSIZEOF(v) ,这里&v是最后一个固定参数的起始地址,再加上其实际占用大小后,就得到了第一个可变参数的起始内存地址。所以我们运行va_start(ap, v)以后,ap指向第一个可变参数在的内存地址,有了这个地址,以后的事情就简单了。 这里要知道两个事情:
⑴在intel+windows的机器上,函数栈的方向是向下的,栈顶指针的内存地址低于栈底指针,所以先进栈的数据是存放在内存的高地址处。
(2)在VC等绝大多数C编译器中,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:最后一个固定参数的地址位于第一个可变参数之下,并且是连续存储的。|--------------------------||
最后一个可变参数
-&高内存地址处|--------------------------||--------------------------||
第N个可变参数
-&va_arg(arg_ptr,int)后arg_ptr所指的地方,|
即第N个可变参数的地址。|--------------- |
|--------------------------||
第一个可变参数
-&va_start(arg_ptr,start)后arg_ptr所指的地方|
即第一个可变参数的地址|--------------- |
|------------------------ --||
最后一个固定参数
-& start的起始地址|-------------- -|
.................|-------------------------- ||
|--------------- |
-& 低内存地址处(4) va_arg():有了va_start的良好基础,我们取得了第一个可变参数的地址,在va_arg()里的任务就是根据指定的参数类型取得本参数的值,并且把指针调到下一个参数的起始地址。因此,现在再来看va_arg()的实现就应该心中有数了:
#define va_arg(ap,t)
( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )这个宏做了两个事情,
①用用户输入的类型名对参数地址进行强制类型转换,得到用户所需要的值
②计算出本参数的实际大小,将指针调到本参数的结尾,也就是下一个参数的首地址,以便后续处理。(5)va_end宏的解释:x86平台定义为ap=(char*)0;使ap不再 指向堆栈,而是跟NULL一样.有些直接定义为((void*)0),这样编译器不会为va_end产生代码,例如gcc在linux的x86平台就是这样定义的. 在这里大家要注意一个问题:由于参数的地址用于va_start宏,所以参数不能声明为寄存器变量或作为函数或数组类型. 关于va_start, va_arg, va_end的描述就是这些了,我们要注意的 是不同的操作系统和硬件平台的定义有些不同,但原理却是相似的.三、可变参数在编程中要注意的问题 因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能 地识别不同参数的个数和类型. 有人会问:那么printf中不是实现了智能识别参数吗?那是因为函数 printf是从固定参数format字符串来分析出参数的类型,再调用va_arg 的来获取可变参数的.也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的. 例如,在C的经典教材《the c programming language》的7.3节中就给出了一个printf的可能实现方式,由于篇幅原因这里不再叙述。四、小结: 1、标准C库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址,编译器是不知道参数的实际数目的。2、在实际应用的代码中,程序员必须自己考虑确定参数数目的办法,如⑴在固定参数中设标志-- printf函数就是用这个办法。后面也有例子。⑵在预先设定一个特殊的结束标记,就是说多输入一个可变参数,调用时要将最后一个可变参数的值设置成这个特殊的值,在函数体中根据这个值判断是否达到参数的结尾。本文前面的代码就是采用这个办法.无论采用哪种办法,程序员都应该在文档中告诉调用者自己的约定。3、实现可变参数的要点就是想办法取得每个参数的地址,取得地址的办法由以下几个因素决定:①函数栈的生长方向②参数的入栈顺序③CPU的对齐方式④内存地址的表达方式结合源代码,我们可以看出va_list的实现是由④决定的,_INTSIZEOF(n)的引入则是由③决定的,他和①②又一起决定了va_start的实现,最后va_end的存在则是良好编程风格的体现,将不再使用的指针设为NULL,这样可以防止以后的误操作。4、取得地址后,再结合参数的类型,程序员就可以正确的处理参数了。理解了以上要点,相信稍有经验的读者就可以写出适合于自己机器的实现来。
本回答被提问者采纳
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。void print(struct student *p)_百度知道
void print(struct student *p)
{ printf(format,p-&num,p-&name,p-&score[0],p-&score[1],p-&score[2]); printf(&\n&);}是什么意思
我有更好的答案
void print(struct student *p){ printf(format,p-&num,p-&name,p-&score[0],p-&score[1],p-&score[2]); printf(&\n&);}这个是一个自定义函数print,调用函数需要传递参数struct student这个结构体的指针*p
采纳率:74%
来自团队:
就是照format提供的格式输出后面的数据,例如format=“%d,%s,%f,%f,%f”那么printf(format,p-&num,p-&name,p-&score[0],p-&score[1],p-&score[2]);等于printf(“%d,%s,%f,%f,%f”,p-&num,p-&name,p-&score[0],p-&score[1],p-&score[2]);printf(&\n&);就是输出一个换行符,
本回答被网友采纳
为您推荐:
其他类似问题
print的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
进程调度 非抢占短作业优先算法源代码
下载积分:1003
内容提示:进程调度 非抢占短作业优先算法源代码
文档格式:DOC|
浏览次数:261|
上传日期: 00:06:32|
文档星级:
全文阅读已结束,如果下载本文需要使用
 1003 积分
下载此文档
该用户还上传了这些文档
进程调度 非抢占短作业优先算法源代码
关注微信公众号编写程序,建立一个通讯录结构,包括姓名、生日(格式为****年**月**日)、电话号码以及所在专业。_百度知道
编写程序,建立一个通讯录结构,包括姓名、生日(格式为****年**月**日)、电话号码以及所在专业。
输入n,n≤10 个联系人信息,按照年龄从大到小依次显示其信息。急求!
我有更好的答案
#include &stdio.h&#include&stdlib.h&#include&string.h&struct node{ char name[10], bir[20], tel[15], dept[20]; char y[5], m[5], d[5];};int comp(const void *a, const void *b){ node *c = (node *)a; node *d = (node *)b; if(c-&y != d-&y)
return strcmp(c-&y, d-&y); else if(c-&m != d-&m)
return strcmp(c-&m, d-&m); else
return strcmp(c-&d, d-&d); }int main() { int n, i, j, node s[10]; printf(&请输出要记录信息的人数: &); scanf(&%d&, &n); for(i = 0; i & i++) {
scanf(&%s %s %s %s&, s[i].name, s[i].bir, s[i].tel, s[i].dept);
for(j = 0; j & 4; j++)
s[i].y[j] = s[i].bir[j];
s[i].y[j] = '\0';
for(j = 6, k = 0; j & 8; j++)
s[i].m[k++] = s[i].bir[j];
s[i].m[k] = '\0';
for(j = 10, k = 0; j & 12; j++)
s[i].d[k++] = s[i].bir[j];
s[i].d[k] = '\0'; } qsort(s, n, sizeof(node), comp); printf(&结果为:\n&); for(i = 0; i & i++)
printf(&%s %s %s %s\n&, s[i].name, s[i].bir, s[i].tel, s[i].dept); return 0;}
采纳率:70%
µ�־וּג#include &stdio.h&int main (void){struct birthday{}struct address_list{char name[20];char phone[20];}s, TXL[10];int i, index, j,scanf(&%d&, &n);for(i = 0; i & i++)scanf(&%s%ld%s&, TXL[i].name, &TXL[i].birthday, TXL[i].phone);for(i=0;i&n-1;i++){index=i;for(j=i+1;j&n;j++){if(TXL[j].birthday&TXL[index].birthday) {s=TXL[j];TXL[j]=TXL[i];TXL[i]=s;}}}for(i = 0; i & i++)printf(&%s %ld %s\n&, TXL[i].name, TXL[i].birthday, TXL[i].phone);return 0;}
1条折叠回答
为您推荐:
其他类似问题
电话号码的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。下次自动登录
现在的位置:
& 综合 & 正文
C语言通讯录管理系统
实现了通讯录的录入信息、保存信息、插入、删除、排序、查找、单个显示等功能。。
完整的代码如下:
#include &stdio.h&
#include &malloc.h&
//得到指向大小为Size的内存区域的首字节的指针//
#include &string.h&
#include &stdlib.h&
//标准库函数//
#define NULL 0
#define LEN sizeof(struct address_list)
//计算字节//
struct address_list
char name[30];
char work[30];
char handset[30];
char email[30];
//电子邮件
char address[30];
//通讯地址
struct address_list *
struct address_list *shifang(struct address_list *head); // 释放内存函数声明
//创建函数,不带头结点的链表
struct address_list *creat(void)
struct address_list *head,*p1,*p2;
char name[20];
p1=(struct address_list *)malloc(LEN);
//强制内存转换
printf("请输入通讯录的内容!\n姓名输入为0时表示创建完毕!\n");
printf("请输入姓名:");
gets(name);
if(strcmp(name,"0")!=0)
strcpy(p1-&name,name);
printf("请输入职业:");
gets(p1-&work);
printf("请输入手机:");
gets(p1-&handset);
printf("请输入电子邮件:"); gets(p1-&email);
printf("请输入通讯地址:");
gets(p1-&address);
head=NULL;
//记录通讯录人数个数
p2-&next=p1;
printf("请输入姓名:");
gets(name);
if(strcmp(name,"0")==0)
p1=(struct address_list *)malloc(LEN);
strcpy(p1-&name,name);
printf("请输入职业:"); gets(p1-&work);
printf("请输入手机:"); gets(p1-&handset);
printf("请输入电子邮件:"); gets(p1-&email);
printf("请输入通讯地址:");
gets(p1-&address);
p2-&next=NULL;
//输出函数
void print(struct address_list *head)
struct address_list *p;
if(head!=NULL)
printf("本通讯录现在共有%d人:\n",n);
printf("---姓名-------职业--------手机-------Email-------通讯地址\n");
printf("==================================\n");
printf("== %s",p-&name); printf("
printf("%s",p-&work); printf("
printf("%s",p-&handset); printf("
printf("%s",p-&email); printf("
printf("%s",p-&address); printf("
}while(p!=NULL);
printf("==================================\n");
printf("通讯录为空,无法输出!\n");
//增加函数
struct address_list *insert(struct address_list *head)
struct address_list *p0,*p1,*p2;
char name[20];
printf("请输入增加的内容:\n");
printf("请输入姓名:"); gets(name);
if(strcmp(name,"0")==0)
printf("姓名不能为0,增加失败!\n");
return(head);
p0=(struct address_list *)malloc(LEN);
strcpy(p0-&name,name);
printf("请输入职业:"); gets(p0-&work);
printf("请输入手机:"); gets(p0-&handset);
printf("请输入电子邮件:"); gets(p0-&email);
printf("请输入通讯地址:");
gets(p0-&address);
if(head==NULL)
p0-&next=NULL;
while(strcmp(p0-&name,p1-&name)&0&&(p1-&next!=NULL))
if(strcmp(p0-&name,p1-&name)&0 || strcmp(p0-&name,p1-&name)==0)
if(head==p1)
p2-&next=p0;
p0-&next=p1;
p1-&next=p0;
p0-&next=NULL;
struct address_list* delete_txl(struct address_list *head)
struct address_list *p,*q;
char name[30];
if(head==NULL)
printf("通讯录为空,无法显示!\n");
printf("请输入需要删除的人的姓名:");
gets(name);
if(strcmp(head-&name,name)==0)
head=head-&
printf("删除操作成功!\n");
q=head,p=head-&
while(p!=NULL)
if(strcmp(p-&name,name)==0)
q-&next=p-&
printf("删除操作成功!\n");
//显示函数
struct address_list *display(struct address_list *head)
struct address_list *p1,*p2;
char name[30];
if(head==NULL)
printf("通讯录为空,无法显示!\n");
printf("请输入需要显示人的姓名:");
gets(name);
while(p1!=NULL)
while((strcmp(p1-&name,name))!=0 && p1-&next!=NULL)
if(strcmp(p1-&name,name)==0)
printf("%s的通讯内容如下:\n",name);
printf("---姓名--------职业--------手机-------Email------通讯地址\n");
printf("==================================\n");
printf("== %s",p1-&name);printf("
printf("%s",p1-&work);printf("
printf("%s",p1-&handset);printf("
printf("%s",p1-&email);printf("
printf("%s",p1-&address); printf("
printf("==================================\n");
printf("此人未在本通讯录中!\n");
return(head);
//排序函数
struct address_list *paixu(struct address_list *head)
struct address_list *p1,*p2;
struct address_list1
char name[30];
char work[30];
char handset[30];
char email[30];
char address[30];
struct address_list1 px[200];
struct address_list1
if(head==NULL)
printf("通讯录为空,无法排序!\n");
return(head);
for(i=0;i&n,p1!=NULL;i++)
strcpy(px[i].name,p1-&name);
strcpy(px[i].work,p1-&work);
strcpy(px[i].handset,p1-&handset);
strcpy(px[i].email,p1-&email);
strcpy(px[i].address,p1-&address);
head=shifang(head);
for(j=0;j&n-1;j++)
for(i=j+1;i&n;i++)
if(strcmp(px[i].name,px[j].name)&0)
temp=px[i];
px[i]=px[j];
p1=(struct address_list *)malloc(LEN);
strcpy(p1-&name,px[0].name);
strcpy(p1-&work,px[0].work);
strcpy(p1-&handset,px[0].handset);
strcpy(p1-&email,px[0].email);
strcpy(p1-&address,px[0].address);
for(i=1;i&n;i++)
p1=(struct address_list *)malloc(LEN);
strcpy(p1-&name,px[i].name);
strcpy(p1-&work,px[i].work);
strcpy(p1-&handset,px[i].handset);
strcpy(p1-&email,px[i].email);
strcpy(p1-&address,px[i].address);
p2-&next=p1;
p2-&next=NULL;
printf("按姓名排序后为:\n");
print(head);
return(head);
//姓名查找函数
struct address_list *search(struct address_list *head)
struct address_list *p1,*p2;
char name[30];
if(head==NULL)
printf("通讯录为空,无法分类查找!\n");
return(head);
printf("********************\n");
printf("**
请输入需要查找的姓名
printf("********************\n");
gets(name);
while(p1!=NULL)
while(strcmp(p1-&name,name)!=0&&p1-&next!=NULL)
if(strcmp(p1-&name,name)==0)
printf("你查找的内容是:\n");
printf("+++++++++++++++++++++++++++++++++++\n");
printf("++ %s
%s\n",p1-&name,p1-&work,p1-&handset,p1-&email,p1-&address);
printf("+++++++++++++++++++++++++++++++++++\n");
printf("此人未在本通讯录中!\n");
return(head);
//释放内存函数
struct address_list *shifang(struct address_list *head)
struct address_list *p1;
while(head!=NULL)
head=head-&
return(head);
//文件写入函数
void save(struct address_list *head)
struct address_list *p1;
char tong[30];
if(head==NULL)
printf("通讯录为空,无法存储!\n");
printf("请输入保存后的文件名:");
gets(tong);
fp=fopen("(tong).txt","w");
if(fp==NULL)
printf("cannot open file\n");
fprintf(fp,"姓名
通讯地址\n");
for(;p1!=NULL;)
fprintf(fp,"%s
%s\n",p1-&name,p1-&work,p1-&handset,p1-&email,p1-&address);
printf("保存完毕!\n");
fclose(fp);
//文件读出函数
struct address_list *load(struct address_list *head)
char tong[30];
struct address_list *p1,*p2;
printf("请输入要输出的文件名:");
gets(tong);
fp=fopen("(tong).txt","r");
if(fp==NULL)
printf("此通讯录名不存在,无法输出!\n");
return(head);
head=shifang(head);
p1=(struct address_list *)malloc(LEN);
fscanf(fp,"%s%s%s%s%s",&p1-&name,&p1-&work,&p1-&handset,&p1-&email,&p1-&address);
if(feof(fp)!=0)
printf("文件为空,无法打开!\n");
return(head);
rewind(fp);
while(feof(fp)==0)
fscanf(fp,"%s%s%s%s%s",&p1-&name,&p1-&work,&p1-&handset,&p1-&email,&p1-&address);
if(feof(fp)!=0)
p2-&next=p1;
p1=(struct address_list *)malloc(LEN);
p2-&next=NULL;
head=head-&
print(head);
printf("打开完毕!\n");
return(head);
fclose(fp);
//综合操作函数
struct address_list *menu(struct address_list *head)
char num[10];
printf("*********************\n");
printf("*** 1 姓名查找
printf("*** 2 单个显示
printf("*** 3 增加
printf("*** 4 退出
printf("*********************\n");
printf("请输入您选择的操作:");
gets(num);
switch(*num)
head=search(head);
//姓名查找
print(head);
head=display(head);
head=insert(head);
print(head);
printf("操作错误,此项不存在!\n");
if(strcmp(num,"6")==0)
void main()
struct address_list *head=NULL;
char num[10];
printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("*=*
printf("*=*
请及时保存创建完毕的通讯录内容!
printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("************************\n");
printf("***
1 创建通讯录
printf("***
2 按名字排序
printf("***
3 综合操作
printf("***
printf("***
printf("***
printf("***
printf("************************\n");
printf("请输入您选择的操作:");
gets(num);
switch(*num)
if(head==NULL)
head=creat();
print(head);
head=shifang(head);
head=creat();
//重新创建
print(head);
head=paixu(head);
head=menu(head);
//综合操作
save(head);
//文件保存
print(head);
head=load(head);
//文件输出
head=delete_txl(head);
print(head);
head=shifang(head);
printf("操作错误,此项不存在!\n");
if(strcmp(num,"7")==0)
【上篇】【下篇】}

我要回帖

更多关于 go print struct 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信