C程序设计语言- 输入与输出-6.1----标准输入与输出、格式化输出(printf)、变长参数表、格式化输入(scanf)、文件访问

来源:互联网 发布:js 数组 splice 删除 编辑:程序博客网 时间:2024/06/07 01:15

前言:继续C系列基础。C系列也快进入尾声了,估计还有俩篇博客。


1.标准输入与输出



2..变长参数表

每一个程序员写的第一个程序大概鼎鼎大名的hello world了,一个简简单单,就那么几行的小程序开启了另一个世界的大门,从此,我们发现了更广阔的世界。而每一个C程序员接触到的第一个函数(除去main函数不算)大概就是printf函数了。这个函数用法很简单灵活,然而里面暗藏玄机,包含了C语言诸多的内容。 
  不知道大家发现没有,printf函数的参数个数是可变的。下面这三个函数都可以完美运行。

  printf("hello,world\n");  printf("this is a int num %d\n",a);  printf("this is a string %s,and a num %d\n",s,a);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  上面这三个函数分别有一个、两个、三个参数。而我们学的C语言函数参数的个数都是固定的,比如下面这个swap()函数,必须传入两个int型指针才能运行。

void swap(int *a,int *b){    int tmp=*a;    *a=*b;    *b=tmp;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  而且C语言里面没有类似C++当中类似默认构造函数的机制,那么printf函数参数个数可变是怎么实现的呢? 
  printf()函数的声明形式是这样: 
  

int printf(char *fmt,...)
  • 1
  • 1

  第一个参数是char型指针,第二个参数是”…”???正是这个“…”实现了printf的变长参数表。 
   
  标准头文件stddrg.h当中包含了一组宏定义,它们对如何遍历参数表进行了定义。 
  va_list 类型用于声明一个变量,该变量将依次引用各参数。我们将该变量称为ap,意思是“参数指针”。宏va_start将ap初始化为指向第一个无名参数的指针。在使用ap 之前,该宏必须被调用一次。参数表必须至少包括一个有名参数,va_start将最后一个有名参数作为起点。 
  每次调用va_arg,该函数都将返回一个参数,并将ap 指向下一个参数。va_arg 使用一个类型名来决定返回的对象类型、指针移动的步长。最后,必须在函数返回之前调用va_end,以完成一些必要的清理工作。

下面使用变长参数表实现printf的两个简单功能,打印整数和字符串。

//main.c文件内容#include<stdio.h>#include "print_dec.h"#include<stdarg.h>void print(char *fmt,...);int main(){    int i;    char s[100];    scanf("%d",&i);    scanf("%s",s);    print("this is a int: %d\n",i);    print("this is a string:\n%s\n",s);    return 0;}void print(char *fmt,...){    int i;    char *m;    va_list p;    va_start(p,fmt);    //将有名参数fmt作为起点,p此时指向第一个无名参数    char *tmp;    for(tmp = fmt;*tmp;tmp++)    {        if(*tmp!='%')        {            putchar(*tmp);            continue;        }        switch(*++tmp)        {            case 'd':                i = va_arg(p,int);                //获得一个无名参数,同时p指向下一个无名参数                print_dec(i);//打印数字i                break;            case 's':                m = va_arg(p,char *);                //获得一个无名参数,同时p指向下一个无名参数                for(;*m;m++)                    putchar(*m);        }       }    va_end(p);//结束时的清理工作}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
//print_dec.c文件内容#include<stdio.h>void print_dec_(int i)//这个函数可以实现打印正整数{    if(i == 0)        putchar(i);    else     {        print_dec_(i/10);        int m = i%10 + '0';        putchar(m);    }}void print_dec(int i)//实现打印0和正整数{    if(i==0)        putchar('0');    else        print_dec_(i);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
//print_dec.h文件内容void print_dec(int i);void print_dec_(int i);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
//makefile文件内容TAG=print.outSRC=main.c print_dec.c print_dec.h${TAG}:${SRC}    gcc -o ${TAG} ${SRC}clean:    rm -rf *.out
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

程序执行效果: 
这里写图片描述



3.文件访问



#include <stdio.h>/* cat: concatenate files, version 1 */main(int argc, char *argv[]){FILE *fp;void filecopy(FILE *, FILE *)if (argc == 1) /* no args; copy standard input */filecopy(stdin, stdout);elsewhile(--argc > 0)if ((fp = fopen(*++argv, "r")) == NULL) {printf("cat: can't open %s\n, *argv);return 1;} else {filecopy(fp, stdout);fclose(fp);}return 0;}/* filecopy: copy file ifp to file ofp */void filecopy(FILE *ifp, FILE *ofp){int c;while ((c = getc(ifp)) != EOF)putc(c, ofp);}


0 0
原创粉丝点击