main()函数

来源:互联网 发布:类似诛仙的小说知乎 编辑:程序博客网 时间:2024/05/29 04:20

请允许我一点点的去补充,如果有问题可以进行留言
说起c语言想必所有用c语言敲过代码的人应该都知道main()函数吧
那么肯定会有人想到为什么用c语言写程序就一定要有main()函数呢

  • 那么整个程序在执行的时候又是如何进行的呢?

  • int main()和void main()有什么区别呢?

  • main函数的具体作用?实现机制?main()函数又是什么函数呢(库函数?系统函数?还是系统调用?)

  • main()函数的参数?

  • 什么情况下我们不需要主函数呢?
    这里没有具体扩展说明不需要主函数的原因

说明:

  1. 那么整个程序在执行的时候又是如何进行的呢?
    目标文件并不能直接执行,他首先需要载入到连接器中。连接器确认main函数为初始进入点(程序开始执行的地方),把符号引用(symbolic reference)绑定到内存地址,把所有的目标文件集中在一起,再加上库文件,从而产生可执行程序。main函数不能被其他函数调用,main函数不一定要放到代码的最后,只需要保证在它被运行的时候所调用的其他的函数能被找到就OK(函数声明)。

  2. int main()和void main()有什么区别呢
    关于main(),因为C99标准定义了main必须返回一个int值,所以int main是最标准的写法,但是在C99之前的一些程序,因为没有相关规范,所以有可能写void main,但是这种写法在一些对c语言标准比较严格的编译器中有可能是导致编译错误的,例如在GCC中,那种写法至少是一个warning。而且,即使你写的void main,编译器编译的时候,还是会返回一个默认的值的,所以两者没有本质的区别。

  3. main函数的具体作用?实现机制?main()函数又是什么函数呢(库函数?系统函数?还是系统调用?)
    (理解中,waiting。。。)

  4. main()函数的参数?
    main()的参数呢是一个可变参数。对于可变参数在《c和指针》 这本书的134页提到(后面我也会具体的写出来)
    我们常用到的是int main(int argc, char* argv[])
    argc指的是命令行参数的个数,argv就是指每个参数是什么?

    还有 int main(int argc, char* argv[], char * envp[] )不常用
    前面两个的意思一样,envp是指环境变量
    举个在Linux上的例子:
    你编写了一个main.c程序,然后在shell中(当前路径下,就是你main.c的路径)输入:gcc main.c 就会生成main.c的可执行程序a.out,你想运行这个程序就需要在命令行(也是当前路径)输入:./a.out
    main.c 就被编译运行了,argc=1;argv[0]=./a.out (这种表现方式你可以与数组进行类比)

main.c#include <stdio.h>#include <stdlib.h>int main(int argc, char* argv[]){    int i = 0;    printf("%d\n",argc);    for(;i < argc;i++)    {        printf("%s ",argv[i]);    }    return 0;}
  1. 什么情况下我们不需要主函数呢?
    这里没有具体扩展说明不需要主函数的原因
    举个列子:对于头文件想必大家都听过(头文件就不需要主函数)
    一个最常见的头文件## stdio.h ##的引用
    那么头文件又怎么写?写了之后又怎么用呢?为什么说头文件中不需要主函数?下面我们简单的建立一个单链表的头文件 list.h (仅仅是为了举例实现list.h的建立,所以只有单链表少部分功能)
    list.h文件
#ifndef LIST_H#define LIST_Htypedef int ElemType;//自定义数据类型typedef enum{ERROR=0,OK=1}Status;typedef struct node{    ElemType data;    struct node* next;  }Node,*PtrNode;typedef struct list{    PtrNode head;    int  cursize;}List;//初始化一个单链表,具有头指针,头结点,头结点->next=NULL;Status InitList(List *plist);  //删除整个链表,使头结点->next=NULL;Status ClearList(List *plist);  Status DestroyList(List *plist)//头插法添加数据;Status Insert_head(List *plist, ElemType x);  //尾插法添加数据;Status Insert_tail(List *plist, ElemType x);  int getlength(List *plist);  //获取单链表的长度;Status printList(List *plist);  //打印整个链表;//获取链表中第i个位置处节点的数据元素;ElemType getElem(List *plist,int i); //从第一个数据开始删除Status Del_head(List *plist);#endif

头文件list.h的实现还需要一个list.cpp文件

list.cpp#include "list.h"#include <stdio.h>PtrNode BuyNode(){    PtrNode s = (PtrNode)malloc(sizeof(Node));    if(s == NULL) exit(-1);    memset(s,0,sizeof(Node));//首次给这片空间赋值,相当于初始化    return s;}//初始化一个单链表,具有头指针,头结点,头结点->next=NULL;Status InitList(List *plist){    if(plist == NULL) return(ERROR);    plist->head = BuyNode();    plist->cursize = 0;    return(OK);}  //删除整个链表,使头结点->next=NULL;Status ClearList(List *plist)  {    if(plist == NULL) return(ERROR);    while(plist->head->next != NULL)    {        PtrNode p = plist->head->next;        plist->head->next = p->next;        free(p);    }    if(plist->head->next == NULL)    return(OK);}Status DestroyList(List *plist){    if(plist == NULL) return(ERROR);    ClearList(plist);    free(plist->head);    plist->head = NULL;    return(OK);}//头插法添加数据;Status Insert_head(List *plist, ElemType x){    if(plist == NULL) return(ERROR);    PtrNode s = BuyNode();    s->next = plist->head->next;    plist->head->next = s;    s->data = x;    plist->cursize += 1;    return(OK);}  //尾插法添加数据;Status Insert_tail(List *plist, ElemType x){    if(plist == NULL) return(ERROR);    PtrNode s = BuyNode();    PtrNode p = plist->head;    while(p->next != NULL)    {        p = p->next;    }    p->next = s;    s->data = x;    plist->cursize += 1;    return(OK);}  int getlength(List *plist)  //获取单链表的长度;{    if(plist == NULL )    {        printf("getlength failed: 链表被摧毁或不存在\n");        return;    }    return(plist->cursize);}Status printList(List *plist)  //打印整个链表;{    if(plist == NULL) return(ERROR);    PtrNode p = plist->head->next;    while(p != NULL)    {        printf("%d\n",p->data);        p = p->next;    }    return(OK);}//获取链表中第i个位置处节点的数据元素;ElemType getElem(List *plist,int i){    if(plist == NULL) return(ERROR);    PtrNode p = plist->head->next; //指向第一个有数据的节点    int val = 1;    for(;val < i;val++)    {        p = p->next;// val=1 p指向第二个。当val=i-1 p指向第i个数据节点    }    return(p->data);}//删除第一个数据Status Del_head(List *plist){    if(plist == NULL) return(ERROR);    PtrNode p = plist->head->next;    plist->head->next = plist->head->next->next;    free(p);    p=NULL;    return(OK);}

当这两个文件都建立好了,那么就说明这个头文件list.h的内容完善了,那么该如何使用呢?文档又该放在什么位置?