c实战开发前奏之指针常用参数传递 三板斧头到家

#include <stdlib.h>/*标准库函数*/
#include <stdio.h>/*I/O函数*/
#include <string.h>/*字符串函数*/
#include <ctype.h>/*字符操作函数*/

typedef struct bookinfo
{
 int id;
 char name[20];
 int count;
 char nametype[20];//分类名称
 char descript[50];//描述
 int country;//国家
}bookinfo;
static bookinfo books;

typedef struct bookcontent
{
 int sectionid;//第一章索引
 char sectionname[10];//第一章
 char paragraphname[10];//第二段
}bookcontent;

typedef enum booktype
{
 STORY=0,
 TECHNOLOGY,
 MISC  
}booktype;

typedef enum countrytype
{
 INNER=0,//国内
 OUTER, //国外 
}countrytype;

//初始化信息
int bookinfo_init(void)
{
 memset(&books, 0x00, sizeof(books));
 books.id=1;
 strcpy((char *)books.name,"方欣");
 books.count=50;
 strcpy((char *)books.nametype,"武打");
 strcpy((char *)books.descript,"方欣2011年09月01日正式入读国定实验幼儿园,她很开心!");
 books.country=-1;
 return 1; 
}

//int的指针的指针 变量存放的是指针
int bookcode=33;
int bookinfo_get_bookcode(int **ppbookcode)
{
 if(NULL == ppbookcode)
 {
  return 0;
 }
 *ppbookcode = &bookcode;//数值变量地址->(&数值变量)
 
 return 1;
}

//char的指针的指针  变量存放的是指针
char bookserial[20]="FX0000000098";
int bookinfo_get_bookserial(char **ppbookserial)
{
 if(NULL == ppbookserial)
 {
  return 0;
 }
 *ppbookserial = bookserial;//数组变量地址->(数组变量名)
 
 return 1;
}
//复合结构的指针的指针 变量存放的是指针
int bookinfo_get(bookinfo **ppbooks)
{
 if(NULL == ppbooks)
 {
  return 0;
 }
 *ppbooks = &books;
 
 return 1;
}
//获取 subtitle
int bookinfo_get_subtitle(char* title)
{
 int len;
  len = sizeof(char);
 title== (char*)malloc(len);
 memset(title,0x00,len);//初始化指针内存
 strcpy(title,"方欣上学");
 return 1;
}

//设置 bookcontent
int bookinfo_set_bookcontent(bookcontent *pbookcontent)
{
 if (NULL == pbookcontent)
 {
  return 0;
 }
 pbookcontent->sectionid = 12;
 strcpy(pbookcontent->sectionname,"第72章");
 strcpy(pbookcontent->paragraphname,"第3回");
 return 1;
}

//获取 bookcontent
int bookinfo_get_bookcontent(bookcontent *pbkcontent)
{
 if (NULL == pbkcontent)
 {
  return 0;
 }
 bookcontent pkcontent;
 int vr;
 vr=bookinfo_set_bookcontent(&pkcontent);
 if (0 == vr)
 {
  return 0;
 }
 pbkcontent->sectionid = pkcontent.sectionid;
 strcpy(pbkcontent->sectionname,pkcontent.sectionname);
 strcpy(pbkcontent->paragraphname,pkcontent.paragraphname);
 return 1;
}

int bookinfo_get_id(int* id)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook))
 {
  return 0;
 }
 (*id) = pbook->id;
 return 1; 
}

int bookinfo_get_name(char* name)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook)| (NULL == name))
 {
  return 0;
 }
 strcpy(name,pbook->name);
 return 1;  
}

int bookinfo_get_count(int* count,int type)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook))
 {
  return 0;
 }
 switch(type)
 {
  case 0:
   *count= pbook->count;
  break;
  case 1:
   *count= 80;
  break;
 }

 return 1; 
}

int bookinfo_get_nametype(char* nametype,booktype type)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook))
 {
  return 0;
 }
 switch(type)
 {
  case STORY:
   strcpy(nametype,"故事");
  break;
  case TECHNOLOGY:
   strcpy(nametype,"技术");
  break;
  case MISC:
   strcpy(nametype,pbook->nametype);
  break;
  default:
  break;
 }

 return 1; 
}
//获取描述
int bookinfo_get_descript(char* descript)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook)||(NULL == descript))
 {
  return 0;
 }
 if(strcmp(pbook->descript, "") == 0)
 {
  descript[0]='\0';//获取 descript[0]={0};
  return 1;
 }
 strcpy(descript,pbook->descript);
 return 1;  
}
//设置描述
int bookinfo_set_descript(char* descript)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook)||(NULL == descript))
 {
  return 0;
 }
 strcpy(pbook->descript, descript);
 return 1;  
}
//获取地区
int bookinfo_get_country(countrytype* country)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook))
 {
  return 0;
 }
 *country=pbook->country;
 return 1;  
}
//设置地区
int bookinfo_set_country(countrytype country)
{
 bookinfo *pbook;
 int r;
 r = bookinfo_get(&pbook);
 if ((1!= r) || (NULL == pbook))
 {
  return 0;
 }
 pbook->country=country;
 return 1;  
}
//遍历二维数组
int foreachArray()
{
 int a[5][3]={0};
 int i=0;
 int j=0;
 int count=0;
 for(i=0;i<5;i++)
 {
  for(j=0;j<3;j++)
  {
   count++;
   a[i][j] =(i+j);
   printf("%d ",a[i][j]);
   if((count%3)==0)
   {
    printf("%d\n",a[i][j]); 
   }
  }
 }
 return 1;
}
/*********************单链表***************************/
//单链表头节点(序号为0) 无数据域 有指针域 存放第一个节点的首地址
//单链表尾节点            有数据域 有指针域 地址域值为NULL空
typedef struct student
{
 int id;
 char name[15];
 struct student* next;//下一个节点的指针
}student;

//初始化线性表,即置单链表的表头指针为空
void init_link(student **pphead)
{
 *pphead=NULL;
 printf("init_link函数执行,初始化成功\n");
}

/*尾插法建立链表*/ 
student* creat_single_tail_link(student* phead)
{
 student* pstudent;//工作节点
 student* ptail;//尾节点
 pstudent=NULL;
 ptail=NULL;
 int i=0;
 while(i<5)
 {
  pstudent=(student*)malloc(sizeof(student));
  if(pstudent==NULL)exit(0);//内存分配失败
  memset(pstudent,0,sizeof(student));

  pstudent->id=i;
  sprintf(pstudent->name,"%s%d","方欣_",i);

  if (phead==NULL)
  {
   phead=pstudent;//新结点插入空表 
  }
  else
  {
   ptail->next=pstudent;//将新结点插到ptail之后 
  }
  
   ptail=pstudent;//尾指针指向新表尾
  i++;
 }
 if (ptail!=NULL)ptail->next=NULL;//对于非空表,将尾结点指针域置空head=s;
 return phead;
}
/*头插法建立链表*/ 
student* creat_single_head_link(student* phead)
{
 student* pstudent;//工作节点
 pstudent=NULL; 
 phead=NULL;
 
 int i=0;
 while(i<5)
 {
  /*头插法建立链表*/ 
  pstudent=(student*)malloc(sizeof(student));
  if(pstudent==NULL)exit(0);//内存分配失败
  memset(pstudent,0,sizeof(student));
  
  pstudent->id=i;
  sprintf(pstudent->name,"%s%d","方欣_",i);

  pstudent->next= phead;//第i=0时 pstudent->next=NULL; 链尾
  phead=pstudent;
  i++;
 }
 return phead;
}
//打印链表,链表的遍历
void print_link(student *phead) 

    if(phead==NULL)   //链表为空 
    { 
        printf("print_link函数执行,链表为空\n"); 
        return;
    } 
    while(phead !=NULL) 
    { 
        printf("%d %s\n",phead->id,phead->name); 
        phead = phead->next; //指针下移
        // phead指向下一个结点 ,类似于数组里面的 i++
    } 
    printf("\n"); 
}

/*打印链表,链表的遍历
void display(student *phead) 

    struct student *p = NULL; 
    for(p = phead; p != NULL; p = p->next) 
    { 
        printf("%d %d\n",p->number,p->grade); 
    } 
}  */

 
//释放单链表中所有的结点,使之成为一个空表 
void clear_link(student *phead) 

    if(phead == NULL) 
    { 
        printf("clear_link函数执行,链表为空\n"); 
        return; 
    } 
    while(phead->next != NULL) 
    { 
     student *ptmp= phead->next;//保存下一结点的指针 
        free(phead); // 释放内存
        phead = ptmp;//表头下移 
    } 
    printf("clear_link函数执行,链表已经清除\n"); 

//清除单链表 
void delete_all_link(student *phead) 

    if(phead == NULL) 
    { 
        printf("clear_link函数执行,链表为空\n"); 
        return; 
    } 
    while(phead->next != NULL) 
    { 
     student *ptmp= phead->next;//保存下一结点的指针 
        free(phead); // 释放内存
        phead = ptmp;//表头下移 
    } 
    printf("clear_link函数执行,链表已经清除\n"); 
}
//返回单链表的长度
int length_link(student *phead) 

    int i = 0; 
    while(phead != NULL) 
    { 
        i++;         //遍历链表大小比链表的实际长度小1 
        phead = phead->next; 
    } 
    printf("length_link函数执行,链表长度 %d \n",i); 
    return i;    //链表的实际长度 

//检查单链表是否为空,若为空则返回1,否则返回0
int isempty_link(student *phead) 

    if(phead == NULL) 
    { 
        printf("isempty_link函数执行,链表为空\n"); 
        return 1; 
    } 
    printf("isempty_link函数执行,链表非空\n"); 
    return 0; 

//返回单链表中第p个结点中的元素,若p超出范围,则停止程序运行
int get_node_link(student *phead, int p) 

    int i=0; 
    if(p < 1) 
    { 
        printf("get_node_link函数执行,p值非法\n"); 
        return 0; 
    } 
    if(phead == NULL) 
    { 
        printf("get_node_link函数执行,链表为空\n"); 
        return 0; 
    } 
    while(phead !=NULL) 
    { 
  //i++  :先引用后增加
  //++i  :先增加后引用
        ++i; 
        if(i == p) 
        { 
            break; 
        } 
        phead = phead->next; //移到下一结点 
    } 
    if(i < p)                  //链表长度不足则退出 
    { 
        printf("get_node_link函数执行,p值超出链表长度\n"); 
        return 0;  
    } 
    return phead->id; 

//从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL 
int* get_node_address_link(student *phead, int x) 

    if(NULL == phead) 
    { 
     printf("get_node_address_link函数执行,链表为空\n"); 
        return NULL; 
    } 
    if(x < 0) 
    { 
        printf("get_node_address_link函数执行,给定值X不合法\n"); 
        return NULL; 
    } 
    while((phead->id != x) && (NULL != phead->next)) //判断是否到链表末尾,以及是否存在所要找的元素 
    { 
        phead = phead->next; 
    } 
    if((phead->id != x) && (phead != NULL)) 
    { 
        printf("get_node_address_link函数执行,在链表中未找到x值\n"); 
        return NULL; 
    } 
    if(phead->id == x) 
    { 
        printf("get_node_address_link函数执行,元素 %d 的地址为 0x%x\n",x,&(phead->id)); 
    } 
    return &(phead->id);//返回元素的地址 

//把单链表中第p个结点的值修改为x的值,若修改成功返回1,否则返回0
int update_node_link(student *phead,int p,int x) 

    student *pstudent; 
    pstudent = phead; 
    int i = 0; 
    if(pstudent==NULL) 
    { 
        printf("update_node_link函数执行,链表为空\n"); 
        return 0; 
    } 
    if(p < 1) 
    { 
        printf("update_node_link函数执行,p值非法\n"); 
        return 0; 
    } 
    while(pstudent !=NULL) 
    { 
        ++i; 
        if(i == p) 
        { 
            break; 
        } 
        pstudent = pstudent->next; //移到下一结点 
    } 
    if(i < p)                  //链表长度不足则退出 
    { 
        printf("update_node_link函数执行,p值超出链表长度\n"); 
        return 0; 
    } 
    phead =pstudent; 
    phead->id = x; 
    printf("update_node_link函数执行\n"); 
    return 1; 
}
 
//向单链表的表头插入一个元素 */
int insert_head_link(student **pphead,student node) 

    student *pstudent; 
    pstudent = (student *)malloc(sizeof(student)); 
    memset(pstudent,0,sizeof(student)); 
    pstudent->id = node.id;
 strcpy(pstudent->name,node.name);
 
    pstudent->next = *pphead; //当前节点的下一节点就是表头
    *pphead = pstudent; 
    printf("insert_head_link函数执行,向表头插入元素成功\n"); 
    return 1; 

//向单链表的末尾添加一个元素 */
int insert_tail_link(student **pphead,student node) 

    student *pstudent; //新节点
    student *ptail; 
    student *ptmp; //定义一个临时链表节点用来存放第一个节点 
   
 ptail = *pphead; 
    ptmp = ptail;
  
    pstudent = (student *)malloc(sizeof(student)); //新节点分配内存 
    memset(pstudent,0,sizeof(student)); 
    pstudent->id = node.id;
 strcpy(pstudent->name,node.name); 
    while(ptail->next != NULL) 
    { 
        ptail = ptail->next; 
    } 
    ptail->next = pstudent;   //将链表末尾节点的下一结点指向新添加的节点 
   
 *pphead = ptmp; 
    printf("insert_tail_link函数执行,向表尾插入元素成功\n"); 
    return 1; 
}

//删除链表中的一个数据
student *delete_node_link(student *phead,int val)
{
 student *pstudent;//当前节点
 student *ptail;//尾节点
    if(phead==NULL)//头节点
 {
  printf("delete_node_link函数执行,链表为空\n");
   exit(0); 
 }
    pstudent=phead;//当前节点指向头节点
    while(val!=pstudent->id && pstudent->next!=NULL)//若pstudent -> next == NULL 则为空链表 
 {
        ptail=pstudent;
        pstudent=pstudent->next;
 }
 //pstudent指向的不是所要找的结点,后面还有结点,
 //使ptail , pstudent向后移动一个结点 ,并继续寻找
    if(val==pstudent->id)
    {
        if(phead==pstudent)
  {
   //找到在第一个结点处 ,删除就是使phead 指向 pstudent所指向的结点
   phead=pstudent->next; 
  }
  else if(pstudent -> next == NULL)
  {
   ptail -> next = NULL;  //找到在尾结点  
  }
        else
  {
   //找到在中间结点pstudent,用ptail结点代替pstudent的位置
   ptail->next=pstudent->next; 
  }
  printf("delete_node_link函数执行:%d\n",val);
  free(pstudent); //释放当前节点
    }
    else
    {
     printf("delete_node_link函数执行,失败:%d\n",val); 
    }
    return phead;
}

//链表冒泡排序
student *pop_sort_link(student *pstudent)
{
    student *pfront;//前一节点
 student *pback;//后一节点
    int tmp;
    for(pfront = pstudent; pfront!=NULL; pfront = pfront->next)
    {
        for(pback = pstudent; pback->next!=NULL; pback=pback->next)
        {
            if(pfront == pback)continue;
            if(pfront->id > pback->id)
            {
                tmp = pfront->id;
                pfront->id = pback->id;
                pback->id = tmp;
            }
        }
    }
    return pstudent;
}

//链表反转
student* reverse_link(student* phead)
{
 if(phead==NULL) 
 { 
  printf("reverse_link函数执行,链表为空\n"); 
  return NULL; 
 }
 student* prever;//反转链表变量
 prever=NULL;
 
 while(phead!=NULL)
 {
   /* ptmp临时保存phead后面的链(指针),因为马上就会被写掉 */
  student* ptmp=phead->next;
   /* 下面两行实际上将phead插入链表prever的头部中 */
  phead->next=prever;//操作链指向 即prever的存放内存地址
  prever=phead;//操作结点 将 phead结点写入 prever
  /* 恢复phead的值,使phead指向下一结点 */
  phead=ptmp;
 }
 /* 这时phead应该为NULL */
 return prever;
}

//链表是否存在环
int is_exits_loop(student* phead)
{
 //定义两个临时链表变量
 student* slow;
 student* fast;
 
 //将链表同时赋给两个链表变量
 slow=phead;
 fast=phead;
 while(fast&&fast->next!=NULL)
 {
  slow=slow->next;// 慢链表一次下移一个节点
  fast=fast->next->next;// 快链表一次下移两个节点
  if(fast==slow) return 1;//存在环 ,退出返回1
 }
 return 0;
}
/*********************单链表***************************/
int main(int argc, char *argv[])
{
 int i;
    char s[128];
    int ret;
    char bookname[20];
 int bookid;
 int bookcount;
 char bookcatory[20];
 char bookdes[50];
 countrytype countryer;
 bookcontent bcontent;
 char* subtitle;
 char* bserial;
 int* bcode;
 
 student *pstudent=NULL;
    //init_link(&pstudent); //链表初始化 
 ret=bookinfo_init();//初始化book信息
 //clrscr();
 printf("********************MENU*******************\n\n");
 printf("|      0: bookinfo_get_id                  |\n");
 printf("|      1: bookinfo_get_name                |\n");
 printf("|      2: bookinfo_get_count               |\n");
 printf("|      3: bookinfo_get_count               |\n");
 printf("|      4: bookinfo_get_nametype            |\n");
 printf("|      5: bookinfo_get_nametype            |\n");
 printf("|      6: bookinfo_get_descript            |\n");
 printf("|      7: bookinfo_get_country             |\n");
 printf("|      8: bookinfo_get_bookcontent         |\n");
 printf("|      9: bookinfo_get_subtitle            |\n");
 printf("|      10: bookinfo_get_bookcode           |\n");
 printf("|      11: bookinfo_get_bookserial         |\n");
 printf("|      12: foreachArray                    |\n");
 printf("|      13: quit                            |\n\n");
 printf("*******************************************\n");
 while(1)
 {
  //clrscr();
  printf("\n 请输入操作选项:"); /*提示输入选项*/
  scanf("%s",s);
  i=atoi(s); /*将输入的字符串转化为整型数*/ //itoa()整型数转化为字符串
  switch(i)
  {
   case 0:
    ret = bookinfo_get_id(&bookid);
    printf("bookid=%d\n",bookid);
   break;
   case 1:
    ret = bookinfo_get_name(bookname);
    printf("bookname=%s\n",bookname);
   break;
   case 2:
    ret = bookinfo_get_count(&bookcount,0);
    printf("bookcount=%d\n",bookcount);
   break;
   case 3:
    ret = bookinfo_get_count(&bookcount,1);
    printf("bookcount=%d\n",bookcount);
   break;
   case 4:
    ret = bookinfo_get_nametype(bookcatory,STORY);
    printf("tname=%s\n",bookcatory);
   break;
   case 5:
    ret = bookinfo_get_nametype(bookcatory,MISC);
    printf("tname=%s\n",bookcatory);
   break;
   case 6:
    strcpy(bookdes,"方欣上的第一节课就是听张老师讲<<蛋蛋狼的故事>>,她很开心。");
    ret = bookinfo_set_descript(bookdes);//设置 set
    ret = bookinfo_get_descript(bookdes);//获取 get
    sprintf(bookdes,"%s_%d_%d\n",bookdes,22,19);//格式化拼接字符串
    //strcat(bookdes,"_上海"); //拼接字符串
    printf("bookdes=%s\n",bookdes);
   break;
   case 7:
    ret =bookinfo_set_country(OUTER);//设置 set
    ret =bookinfo_get_country(&countryer);//获取 get
    printf("countryer=%d\n",countryer);
   break;
   case 8:
    ret =bookinfo_get_bookcontent(&bcontent);//获取 get
    printf("sectionid=%d\nsectionname=%s\nparagraphname=%s\n",bcontent.sectionid,bcontent.sectionname,bcontent.paragraphname);
   break;
   case 9:
    ret =bookinfo_get_subtitle(subtitle);
    printf("subtitle=%s\n",subtitle);
    free(subtitle);
   break;
   case 10:
    ret =bookinfo_get_bookcode(&bcode);
    printf("bcode=%d\n",*bcode);
   break;
   case 11:
    ret =bookinfo_get_bookserial(&bserial);
    printf("bserial=%s\n",bserial);
   break;
   case 12:
    ret =foreachArray();//打印二维数组
     //printf("bserial=%d%%\n",35);打印出35%
   break;
   case 13:
    pstudent=creat_single_tail_link(pstudent); //尾插法创建单链表 
       print_link(pstudent); //打印单链表
   break;
   case 14:
    pstudent=creat_single_head_link(pstudent);//头插法创建单链表 
       print_link(pstudent); //打印单链表 
   break;
   case 15:
    exit(0);
   break;
   default:
   break;
  }
 }
    return 0;
}
备注:数组名是指针常量。

原文地址:https://www.cnblogs.com/fx2008/p/2178990.html