zoukankan      html  css  js  c++  java
  • 《C语言—从入门到项目实践》Issue分析及总结

    在学习《C语言—从入门到项目实践》总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    《C语言—从入门到项目实践》(超值版)——聚慕课教育研发中心 编著

    Issue分析及总结

    第四章 数制与数据类型

    问题描述:4.7.3中定义复杂的声明别名中(2)(3)不理解?

    未解决!

    第11章 指针——重点

    注意事项:

    1)刚定义的指针变量并未指向某个具体的位置(称为悬空指针)。使用悬空指针容易破坏系统,导致系统瘫痪。

    2)指针变量只能存放指针(地址),不要将一个非零数(或任何其他非地址类型的数据)赋给一个指针变量。

    备注:0除外,如int *p=0;——>表示指针指向空指针,C语言中用NULL表示空指针,表示没有指向任何对象。

    3)引用一个数组元素有两种方法:下标法,即采用array[i]形式直接访问数组元素;指针法,即采用*(array+i)或*(pointer+i)形式间接访问数组元素。其中,array是数组名,pointer是指向数组的指针变量。

    4)字符数组可以用数组名来一次性的输出它的全部元素(printf("%s",string);),其他类型的数组都不行(只能逐个元素输出)。

    1.问题描述:指针的类型与指针所指向的类型的区别?

    答:指针的类型是指针本身的类型,指针所指向的类型是:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩余部分。如:int *ptr——>指针的类型是:int *;指针所指向的类型是int。

    2.问题描述:数组指针和指针数组的区别?

    答:如果指针p指向二维数组的某一行,则p+1就指向类该二维数组的下一行。这样的指针称为数组指针。如:int array[2][3]={1,2,3,4,5,6};int (*p) [3];——>表明指针p指向一个含有3个元素的一维整型数组,p的值就是该一维数组的首地址。

    所以数组指针也称指向一维数组的指针,亦称行指针。

    11-9.c

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include <stdio.h>
     3 int main(void)
     4 {
     5     int array[2][3] = { 1,2,3,4,5,6 };      /*定义一个二维数组*/
     6     int i, j;
     7     int(*p)[3];       /*定义一个数组指针*/
     8     p = array;      /*p指向array下标为0那一行的首地址*/
     9     for (i = 0; i<2; i++)
    10     {
    11         for (j = 0; j<3; j++)
    12             printf("array[%d][%d]=%d
    ", i, j, p[i][j]);
    13     }
    14     return 0;
    15 }

    问题:p[i][j]输出是怎么回事???这是下标输出,还可以使用*(p[i]+j)或*(*(p+i)+j)或*(p+i)[j],即*(p+i)就等价于p[i]。*(p+i)是指针法,p[i]是下标法。
    不能使用p[i]或*p[i]或*(p+i),因为这些都只能找到行,找不到列,所以当i等于0,(p[i]或*p[i]或*(p+i))都输出0,当i等于1,p[i]或*p[i]或*(p+i))都输出1

    一维数组指针

     11-16.c

     1 #include <stdio.h>
     2 main()
     3 {
     4   int array[10], *pointer=array, i; 
     5   printf("Input 10 numbers: ");
     6   for(i=0; i<10; i++)
     7          scanf("%d", pointer+i);           /*使用指针变量来输入数组元素的值*/
     8         printf("array[10]: ");
     9    for(i=0; i<10; i++)
    10          printf("%d  ", *(pointer+i));    /*使用指向数组的指针变量输出数组*/
    11         printf("
    ");
    12 }

    int array[10], *pointer=array;——>pointer+i和array+i都是数组元素array[i]的地址,或者说它们都指向array数组的第i个元素。*(pointer+i)和*(array+i)就是pointer+i或array+i所指向的数组元素,即array[i]。

    多维数组指针——以二维为例

     11-17.c

     1 #include <stdio.h>
     2 int main(void)
     3 {
     4    int array[2][3]={1,2,3,4,5,6};
     5    int i,j,*p;
     6    p=&array[0][0];//等价于p=array
     7    printf("使用下标访问数组元素
    ");
     8    for(i=0;i<2;i++)
     9    {
    10    for(j=0;j<3;j++)
    11       printf("array[%d][%d]=%d
    ",i,j,array[i][j]);
    12    }
    13    printf("使用数组名访问数组元素
    ");
    14    for(i=0;i<2;i++)
    15    {
    16    for(j=0;j<3;j++)
    17    printf("array[%d][%d]=%d
    ",i,j,*(*(array+i)+j));
    18    }
    19    printf("使用指针名访问数组元素
    ");
    20    for(i=0;i<2;i++)
    21    {
    22    for(j=0;j<3;j++)
    23    printf("array[%d][%d]=%d
    ",i,j,*(p+3*i+j));
    24    }
    25    return 0;
    26 }

    注意此处二维数组指针当采用指针名访问数组元素(*(p+3*i+j)))和之前的数组指针(*(*(p+i)+j))的不同,因为之前定义的差别!!!

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include <stdio.h>
     3 main()
     4 {
     5     static int day_tab[2][13] = {
     6         { 0,31,28,31,30,31,30,31,31,30,31,30,31 },      //没有闰年的月份天数
     7         { 0,31,29,31,30,31,30,31,31,30,31,30,31 } };    //闰年的月份天数
     8     int y, m, d;
     9     scanf("%d%d%d", &y, &m, &d);
    10     printf("%d
    ", day_of_year(day_tab, y, m, d));     /*实参为二维数组名*/
    11 }
    12 day_of_year(day_tab, year, month, day)
    13     int *day_tab;          /*形式参数为指针*/
    14     int year, month, day;
    15     {
    16         int i, j;
    17         i = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    18         for (j = 1; j<month; j++)             /* day_tab+i*13+j:对二维数组中元素进行地址变换 */
    19             day += *(day_tab + i * 13 + j);
    20         return(day);
    21     }

    说明:此代码会发出一个警告:c(10): warning C4013: “day_of_year”未定义;假设外部返回 int

    还可参看:数组指针和指针数组的区别——https://www.cnblogs.com/mq0036/p/3382732.html

    3.问题描述:*(p1-1)的值与变量b的值相同,是巧合吗?

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include <stdio.h>
     3 int main(void)
     4 {
     5     int a = 1, b = 10;
     6     int *p1, *p2;
     7     p1 = &a;                                             /*指针赋值*/
     8     p2 = &b;
     9     printf("p1地址是%d,p1存储的值是%d
    ", p1, *p1);       /*输出*/
    10     printf("p2地址是%d,p2存储的值是%d
    ", p2, *p2);       /*输出*/
    11     printf("p1-1地址存储的值是%d
    ", *(p1 - 1));    /*地址-1后存储的值*/
    12     printf("p1地址中的值-1后的值是%d
    ", *p1 - 1);    /*值-1后的值*/
    13     printf("*(p1-1)的值和*p1-1的值不同
    ");
    14     return 0;
    15 }

    答:不是巧合。原因是a和b是局部变量,局部变量存储在栈中,而栈是向低地址扩展的存储空间(如果是堆就相反了),又因为int类型占用4个字节,所以a的地址比b的地址大4个字节,p1-1表示a的地址减少4个字节后的地址,也就是p2所指向的变量b,所以是10。

    第17章 动态数据结构——重点

    1.问题描述:17.2中的链表的建立

    代码注释及说明:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include "stdio.h"
     3 #include "malloc.h"
     4 #define NULL 0                          /*令NULL为0,用它表示空地址*/
     5 /*LEN代表struct stu结构体类型数据的长度*/
     6 #define LEN sizeof (struct stu) 
     7 struct stu
     8 {
     9     long int num;
    10     float score;
    11     struct stu *next;
    12 };
    13 int n;
    14 struct stu *creat()                      /*此函数带回一个指向链表头的指针*/
    15 {
    16     struct stu *head, *p1, *p2;
    17     n = 0;                                    /*n为结点的个数*/
    18     p1 = p2 = (struct stu *)malloc(LEN);        /*开辟一个新单元,p1指向p2,共同指向这个新单元*/
    19     scanf("%ld,%f", &p1->num, &p1->score);//如:输入:1,1.5——>p1指向该节点,p2也指向该节点
    20     head = NULL;//头指针为空
    21     while (p1->num != 0)
    22     {
    23         n = n + 1;//链表节点个数的递增
    24         if (n == 1)head = p1;//如果是第一个节点,令头指针head指向p1
    25         else p2->next = p1;//如果不是第一个节点,令p2的next指针指向p1
    26         p2 = p1;//p2指针向后移动,p2指向p1(刚输入的节点)
    27         p1 = (struct stu *)malloc(LEN);//p1指向刚开辟的一个新单元
    28         scanf("%ld,%f", &p1->num, &p1->score);//如:输入:1,1.5——>p1指向该节点
    29     }
    30     p2->next = NULL;//输入完毕,令p2的next域指向空(链表的结尾)
    31     return(head);                            /*返回链表的头地址*/
    32 }
    33 void main()
    34 {
    35     creat();//此处可以调用create函数创建的链表
    36 }

    思路:p1指向新插入的节点,p2的next域指向链表新插入的节点p1——>实现链接上节点p1,p2通过指向p1实现不断后移。

    2.问题描述:17.10中的迷宫问题求解的思路,怎么找到出口,路过的下标为什么会少一个?

    思路:1)通过探测一个位置的右,下,左,上的位置(标志位)是否为0,而判定下一步是否可以移动到这个点;2)对走过的点,将其标志位设置为0,并将此点入栈;3)如果此点四周都无法走通,出栈,判断刚出栈的点是否可以走通,依次下去;4)如果可以走到出口位置,表示存在这样的路径,如果走不到(即最后栈为空),表明不存在这样的路径。

    因为涉及到对已经走过的点的出栈,所以(3行6列)出栈后后续路径可以走通了,输出了路径,最后不存在(3,6)

    第18章 C语言经典排序法——重点

    1.问题描述:此章的程序用(.c)后缀命名后运行总是报错,如不存在iostream.h等,struct SqList &L报错存在正文时不允许未命名的原型函数

    说明:此章的代码不支持C,需要用(.cpp)命名。

    2.问题描述:18-3.c中对数组进行快速排序,运行报错?

    代码注释及说明:

     1 #include <stdio.h>
     2 int partions(int arr[],int low,int high)// 划分函数
     3 {
     4     int prvotkey= arr[low];  //提取出低区的关键字
     5     arr[0]= arr[low];
     6     while (low<high)  //对低区和高区的数组下标进行比较
     7     {
     8         while (low<high&& arr[high]>=prvotkey)
     9             --high;   //高区的关键字就向前移动
    10         arr[low]= arr[high];   //高区的数组元素也向前移动
    11             while (low<high&& arr[low]<=prvotkey) 
    12                 ++low;   //低区的关键字向后移动
    13             arr[high]= arr[low];   //低区的数组元素向后移动
    14     }
    15     arr[low]= arr[0];
    16     return low;
    17 }
    18 void qsort(int arr[],int low,int high)
    19 {
    20     int prvotloc;    //枢轴
    21     if(low<high)
    22     {
    23         prvotloc=partions(arr,low,high);    /*将第一次排序的结果作为枢轴*/
    24         qsort(arr,low,prvotloc-1);     /*递归调用排序,由low 到prvotloc-1*/
    25         qsort(arr,prvotloc+1,high);    /*递归调用排序,由 prvotloc+1到 high*/
    26     }
    27 }
    28 void quicksort(int arr[],int n)
    29 {
    30     qsort(arr,1,n);                  /*第一个作为枢轴 ,从第一个排到第n个*/
    31 }
    32 void main()
    33 {
    34     int a[11]={0,2,32,43,23,45,36,57,14,27,39};
    35     int b,c;
    36     for (b=1;b<11;b++)
    37         printf("%3d",a[b]);
    38     printf("
    ");
    39     quicksort(a,11);
    40     for (c=1;c<11;c++)
    41         printf("%3d",a[c]);
    42     printf("
      ");
    43 }

    原因:数组越界,代码未更改!

    3.问题描述:18-8.c中对数组进行快速排序,运行报错?

    代码注释及说明:

     1 //#define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 typedef int InfoType;             /* 定义其他数据项的类型*/
     4 #define MAXSIZE 20                 /* 一个用做示例的小顺序表的最大长度*/
     5 typedef int KeyType;             /* 定义关键字类型为整型*/
     6 struct RedType                 /* 记录类型*/
     7 {
     8     KeyType key;                     /* 关键字项*/
     9     InfoType otherinfo;             /* 其他数据项,具体类型在主程中定义*/
    10 };
    11 struct SqList                     /* 顺序表类型*/
    12 {
    13     RedType r[MAXSIZE + 1];             /* r[0]闲置或用做哨兵单元*/
    14     int length;                     /* 顺序表长度*/
    15 };
    16 int SelectMinKey(SqList L, int i)
    17 { /* 返回在L.r[i..L.length]中key最小的记录的序号*/
    18     KeyType min;
    19     int j, k;
    20     k = i;                             /* 设第i个为最小*/
    21     min = L.r[i].key;
    22     for (j = i + 1; j <= L.length; j++)
    23         if (L.r[j].key<min)             /* 找到更小的*/
    24         {
    25             k = j;
    26             min = L.r[j].key;
    27         }
    28     return k;
    29 }
    30 void SelectSort(SqList &L)
    31 { /* 对顺序表L作简单选择排序*/
    32     int i, j;
    33     RedType t;
    34     for (i = 1; i<L.length; ++i)
    35     { /*  选择第i小的记录,并交换到位*/
    36         j = SelectMinKey(L, i);             /* 在L.r[i..L.length]中选择key最小的记录*/
    37         if (i != j)
    38         { /* 与第i个记录交换*/
    39             t = L.r[i];
    40             L.r[i] = L.r[j];
    41             L.r[j] = t;
    42         }
    43     }
    44 }
    45 void print(SqList L)
    46 {
    47     int i;
    48     for (i = 1; i <= L.length; i++)
    49         printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    50     printf("
    ");
    51 }
    52 #define N 8
    53 void main()
    54 {
    55     RedType d[N] = { { 49,1 },{ 38,2 },{ 65,3 },{ 97,4 },{ 76,5 },{ 13,6 },{ 27,7 },{ 49,8 } };
    56     SqList l;
    57     int i;
    58     for (i = 0; i<N; i++)
    59         l.r[i + 1] = d[i];
    60     l.length = N;
    61     printf("排序前:
    ");
    62     print(l);
    63     SelectSort(l);
    64     printf("排序后:
    ");
    65     print(l);
    66 }

    说明:L在经过一次排序后是   L    {r=0x005bfa80 {{key=-858993460 otherinfo=-858993460 }, {key=13 otherinfo=6 }, {key=38 otherinfo=2 }, ...} ...}    SqList &;因为存储时下标为0的节点没有存储内容,所以都是随机值。

    4.问题描述:18-9.c中对数组进行树形选择排序,运行报错?

    代码注释及说明:

     1 #include<string.h>
     2 #include<ctype.h>
     3 #include<malloc.h>        /*malloc()等*/
     4 #include<limits.h>        /*INT_MAX等*/
     5 #include<stdio.h>         /*EOF(=^Z或F6),NULL*/
     6 #include<stdlib.h>        /*atoi()*/
     7 #include<io.h>          /*eof()*/
     8 #include<math.h>        /*floor(),ceil(),abs()*/
     9 #include<process.h>        /*exit()*/
    10 //#include<iostream.h>      /*cout,cin*/
    11 /* 函数结果状态代码*/
    12 #define TRUE 1
    13 #define FALSE 0
    14 #define OK 1
    15 #define ERROR 0
    16 #define INFEASIBLE -1
    17 typedef int Status;     /*Status是函数的类型,其值是函数结果状态代码,如OK*/
    18 typedef int Boolean;     /*Boolean是布尔类型,其值是TRUE或FALSE*/
    19 typedef int InfoType;     /*定义其他数据项的类型*/
    20 #define MAXSIZE 20         /*一个用做示例的小顺序表的最大长度*/
    21 typedef int KeyType;     /*定义关键字类型为整型*/
    22 struct RedType         /*记录类型*/
    23 {
    24     KeyType key;             /*关键字项*/
    25     InfoType otherinfo;     /*其他数据项,具体类型在主程序中定义*/
    26 };
    27 
    28 struct SqList             /*顺序表类型*/
    29 {
    30     struct RedType r[MAXSIZE + 1];     /*r[0]闲置或用做哨兵单元*/
    31     int length;             /*顺序表长度*/
    32 };
    33 
    34 void TreeSort(SqList &L)
    35 { /*树形选择排序*/
    36     int i, j, j1, k, k1, l, n = L.length;
    37     RedType *t;
    38     l = (int)ceil(log(n) / log(2)) + 1;             /*完全二叉树的层数*/
    39     k = (int)pow(2, l) - 1;                         /*l层完全二叉树的结点总数*/
    40     k1 = (int)pow(2, l - 1) - 1;                     /*l-1层完全二叉树的结点总数*/
    41     t = (RedType*)malloc(k*sizeof(RedType));     /*二叉树采用顺序存储结构*/
    42     for (i = 1; i <= n; i++)                         /*将L.r赋给叶子结点*/
    43         t[k1 + i - 1] = L.r[i];
    44     for (i = k1 + n; i<k; i++)                     /*给多余的叶子的关键字赋无穷大*/
    45         t[i].key = INT_MAX;
    46     j1 = k1;
    47     j = k;
    48     while (j1)
    49     { /*给非叶子结点赋值*/
    50         for (i = j1; i<j; i += 2)
    51             t[i].key<t[i + 1].key ? (t[(i + 1) / 2 - 1] = t[i]) : (t[(i + 1) / 2 - 1] = t[i + 1]);
    52         j = j1;
    53         j1 = (j1 - 1) / 2;
    54     }
    55     for (i = 0; i<n; i++)
    56     {
    57         L.r[i + 1] = t[0];         /*将当前最小值赋给L.r[i]*/
    58         j1 = 0;
    59         for (j = 1; j<l; j++)         /*沿树根找结点t[0]在叶子中的序号j1*/
    60             t[2 * j1 + 1].key == t[j1].key ? (j1 = 2 * j1 + 1) : (j1 = 2 * j1 + 2);
    61         t[j1].key = INT_MAX;
    62         while (j1)
    63         {
    64             j1 = (j1 + 1) / 2 - 1;         /*序号为j1的结点的双亲结点序号*/
    65             t[2 * j1 + 1].key <= t[2 * j1 + 2].key ? (t[j1] = t[2 * j1 + 1]) : (t[j1] = t[2 * j1 + 2]);
    66         }
    67     }
    68     free(t);
    69 }
    70 
    71 void print(struct SqList L)
    72 {
    73     int i;
    74     for (i = 1; i <= L.length; i++)
    75         printf("(%d,%d)", L.r[i].key, L.r[i].otherinfo);
    76     printf("
    ");
    77 }
    78 
    79 #define N 8
    80 void main()
    81 {
    82     struct RedType d[N] = { { 49,1 },{ 38,2 },{ 65,3 },{ 97,4 },{ 76,5 },{ 13,6 },{ 27,7 },{ 49,8 } };
    83     struct SqList l;
    84     int i;
    85     for (i = 0; i<N; i++)
    86         l.r[i + 1] = d[i];
    87     l.length = N;
    88     printf("排序前:
    ");
    89     print(l);
    90     TreeSort(l);
    91     printf("排序后:
    ");
    92     print(l);
    93 }
    说明:需要将//#include<iostream.h>      /*cout,cin*/注释掉,如果不注释,会报错:error C1083: 无法打开包括文件: “iostream.h”: No such file or directory

     18-2.c也有这个问题,也需要注释掉。

    4.问题描述:18-12.c中对链式进行基数排序,运行报错:error C4996: 'itoa': The POSIX name for this item is deprecated?

    代码注释及说明:

      1 #define _CRT_NONSTDC_NO_DEPRECATE
      2 #define _CRT_SECURE_NO_WARNINGS
      3 #include<string.h>
      4 #include<ctype.h>
      5 #include<malloc.h>                 //malloc()等
      6 #include<limits.h>                 //INT_MAX等
      7 #include<stdio.h>                 //EOF(=^Z或F6),NULL
      8 #include<stdlib.h>                 //atoi()
      9 #include<io.h>                     //eof()
     10 #include<math.h>                 //floor(),ceil(),abs()
     11 #include<process.h>             //exit()
     12 //#include<iostream.h>             //cout,cin
     13 /* 函数结果状态代码*/
     14 #define TRUE 1
     15 #define FALSE 0
     16 #define OK 1
     17 #define ERROR 0
     18 #define INFEASIBLE -1
     19 typedef int Status;         /*Status是函数的类型,其值是函数结果状态代码,如OK等*/
     20 typedef int Boolean;         /*Boolean是布尔类型,其值是TRUE或FALSE*/
     21 #define MAX_NUM_OF_KEY 8     /*关键字项数的最大值*/
     22 #define RADIX 10             /*关键字基数,此时是十进制整数的基数*/
     23 #define MAX_SPACE 1000
     24 
     25 typedef int InfoType;         /*定义其他数据项的类型*/
     26 typedef int KeyType;         /*定义RedType类型的关键字为整型*/
     27 struct RedType             /*记录类型(同c10-1.h)*/
     28 {
     29     KeyType key;                 /*关键字项*/
     30     InfoType otherinfo;         /*其他数据项*/
     31 };
     32 typedef char KeysType;     /*定义关键字类型为字符型*/
     33 
     34 struct SLCell                 /*静态链表的结点类型*/
     35 {
     36     KeysType keys[MAX_NUM_OF_KEY];     /* 关键字*/
     37     InfoType otheritems;         /*其他数据项*/
     38     int next;
     39 };
     40 
     41 
     42 struct SLList                 /*静态链表类型*/
     43 {
     44     SLCell r[MAX_SPACE];         /*静态链表的可利用空间,r[0]为头结点*/
     45     int keynum;                 /*记录的当前关键字个数*/
     46     int recnum;                 /*静态链表的当前长度*/
     47 };
     48 
     49 typedef int ArrType[RADIX];
     50 void InitList(SLList &L, RedType D[], int n)
     51 { /*初始化静态链表L(把数组D中的数据存于L中)*/
     52     char c[MAX_NUM_OF_KEY], c1[MAX_NUM_OF_KEY];
     53     int i, j, max = D[0].key;         /*max为关键字的最大值*/
     54     for (i = 1; i<n; i++)
     55         if (max<D[i].key)
     56             max = D[i].key;
     57     L.keynum = int(ceil(log10(max)));
     58     L.recnum = n;
     59     for (i = 1; i <= n; i++)
     60     {
     61         L.r[i].otheritems = D[i - 1].otherinfo;
     62         itoa(D[i - 1].key, c, 10);     /* 将十进制整型转化为字符型,存入c*/
     63         for (j = strlen(c); j<L.keynum; j++)     /*若c的长度小于max的位数,在c前补'0'*/
     64         {
     65             strcpy(c1, "0");
     66             strcat(c1, c);
     67             strcpy(c, c1);
     68         }
     69         for (j = 0; j<L.keynum; j++)
     70             L.r[i].keys[j] = c[L.keynum - 1 - j];
     71     }
     72 }
     73 
     74 int ord(char c)
     75 { /*返回k的映射(个位整数)*/
     76     return c - '0';
     77 }
     78 
     79 void Distribute(SLCell r[], int i, ArrType f, ArrType e)
     80 { /*静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。本算法按*/
     81   /*第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同*/
     82   /*f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录*/
     83     int j, p;
     84     for (j = 0; j<RADIX; ++j)
     85         f[j] = 0; /*各子表初始化为空表*/
     86     for (p = r[0].next; p; p = r[p].next)
     87     {
     88         j = ord(r[p].keys[i]);         /*ord将记录中第i个关键字映射到[0..RADIX-1]*/
     89         if (!f[j])
     90             f[j] = p;
     91         else
     92             r[e[j]].next = p;
     93         e[j] = p;                     /*将p所指的结点插入第j个子表中*/
     94     }
     95 }
     96 
     97 int succ(int i)
     98 { /* 求后继函数*/
     99     return ++i;
    100 }
    101 
    102 void Collect(SLCell r[], ArrType f, ArrType e)
    103 { /*本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成*/
    104   /*一个链表,e[0..RADIX-1]为各子表的尾指针*/
    105     int j, t;
    106     for (j = 0; !f[j]; j = succ(j));    /*找第一个非空子表,succ为求后继函数*/
    107     r[0].next = f[j];
    108     t = e[j];                     /*r[0].next指向第一个非空子表中第一个结点*/
    109     while (j<RADIX - 1)
    110     {
    111         for (j = succ(j); j<RADIX - 1 && !f[j]; j = succ(j)); /*找下一个非空子表*/
    112         if (f[j])
    113         { /*链接两个非空子表*/
    114             r[t].next = f[j];
    115             t = e[j];
    116         }
    117     }
    118     r[t].next = 0;                /*t指向最后一个非空子表中的最后一个结点*/
    119 }
    120 
    121 void printl(SLList L)
    122 { /*按链表输出静态链表*/
    123     int i = L.r[0].next, j;
    124     while (i)
    125     {
    126         for (j = L.keynum - 1; j >= 0; j--)
    127             printf("%c", L.r[i].keys[j]);
    128         printf(" ");
    129         i = L.r[i].next;
    130     }
    131 }
    132 
    133 void RadixSort(SLList &L)
    134 { /*L是采用静态链表表示的顺序表。对L作基数排序,使得L成为按关键字*/
    135   /*自小到大的有序静态链表,L.r[0]为头结点*/
    136     int i;
    137     ArrType f, e;
    138     for (i = 0; i<L.recnum; ++i)
    139         L.r[i].next = i + 1;
    140     L.r[L.recnum].next = 0;             /*将L改造为静态链表*/
    141     for (i = 0; i<L.keynum; ++i)
    142     { /*按最低位优先依次对各关键字进行分配和收集*/
    143         Distribute(L.r, i, f, e);         /*第i趟分配*/
    144         Collect(L.r, f, e);             /*第i趟收集*/
    145         printf("第%d趟收集后:
    ", i + 1);
    146         printl(L);
    147         printf("
    ");
    148     }
    149 }
    150 
    151 void print(SLList L)
    152 { /*按数组序号输出静态链表*/
    153     int i, j;
    154     printf("keynum=%d recnum=%d
    ", L.keynum, L.recnum);
    155     for (i = 1; i <= L.recnum; i++)
    156     {
    157         printf("keys=");
    158         for (j = L.keynum - 1; j >= 0; j--)
    159             printf("%c", L.r[i].keys[j]);
    160         printf(" otheritems=%d next=%d
    ", L.r[i].otheritems, L.r[i].next);
    161     }
    162 }
    163 
    164 void Sort(SLList L, int adr[])     /*改此句(类型)*/
    165 { /*求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号*/
    166     int i = 1, p = L.r[0].next;
    167     while (p)
    168     {
    169         adr[i++] = p;
    170         p = L.r[p].next;
    171     }
    172 }
    173 
    174 void Rearrange(SLList &L, int adr[])    /*改此句(类型)*/
    175 { /*adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录*/
    176   /*本算法按adr重排L.r,使其有序(L的类型有变)*/
    177     int i, j, k;
    178     for (i = 1; i<L.recnum; ++i)         /*改此句(类型)*/
    179         if (adr[i] != i)
    180         {
    181             j = i;
    182             L.r[0] = L.r[i];                 /*暂存记录L.r[i]*/
    183             while (adr[j] != i)
    184             { /*调整L.r[adr[j]]的记录到位直到adr[j]=i为止*/
    185                 k = adr[j];
    186                 L.r[j] = L.r[k];
    187                 adr[j] = j;
    188                 j = k;                             /*记录按序到位*/
    189             }
    190             L.r[j] = L.r[0];
    191             adr[j] = j;
    192         }
    193 }
    194 
    195 #define N 10
    196 void main()
    197 {
    198     RedType d[N] = { { 278,1 },{ 109,2 },{ 63,3 },{ 930,4 },{ 589,5 },
    199     { 184,6 },{ 505,7 },{ 269,8 },{ 8,9 },{ 83,10 } };
    200     SLList l;
    201     int *adr;
    202     InitList(l, d, N);
    203     printf("排序前(next域还没赋值):
    ");
    204     print(l);
    205     RadixSort(l);
    206     printf("排序后(静态链表):
    ");
    207     print(l);
    208     adr = (int*)malloc((l.recnum)*sizeof(int));
    209     Sort(l, adr);
    210     Rearrange(l, adr);
    211     printf("排序后(重排记录):
    ");
    212     print(l);
    213 }

    原因:新版本的vs对旧有的函数itoa进行了安全检查,所以使用新版本的vs会提示错误,而旧版本的没问题。

    解决办法:
    1)使用新函数 _itoa
    2)如果非要使用旧函数也是可以的,加上宏定义即可
    #define _CRT_NONSTDC_NO_DEPRECATE
    #define _CRT_SECURE_NO_WARNINGS

    在学习《C语言—从入门到项目实践》总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 传球游戏
    Java实现 蓝桥杯VIP 算法训练 Hanoi问题
    Java实现 蓝桥杯VIP 算法训练 蜜蜂飞舞
    Java实现 蓝桥杯VIP 算法训练 奇偶判断
    Java实现 蓝桥杯VIP 算法训练 传球游戏
    Java实现 蓝桥杯VIP 算法训练 Hanoi问题
    Java实现 蓝桥杯VIP 算法训练 Hanoi问题
    Java实现 蓝桥杯VIP 算法训练 蜜蜂飞舞
    Java实现 蓝桥杯VIP 算法训练 蜜蜂飞舞
    Qt: 访问容器(三种方法,加上for循环就四种了)good
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/C_Language_FromEntryToProjectPractice_IssueAnalysisAndSummary.html
Copyright © 2011-2022 走看看