main()函数

请允许我一点点的去补充,如果有问题可以进行留言
说起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_H

typedef 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的内容完善了,那么该如何使用呢?文档又该放在什么位置?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值