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,转载请注明出处。

  • 相关阅读:
    html页面小技巧
    文件上传动态获取文件名
    thymeleaf之下拉框回显选中
    地图/导航控件哪家强?DevExpress WPF v19.2帮你忙
    Web UI开发神器—Kendo UI for jQuery数据管理之过滤操作
    开启.NET Core 3时代,DevExpress v19.2.5带你全新启航
    DevExpress WPF 2020全新出发,功能计划蓝图一览
    2020还有9天!Winforms开发有哪些期待?DevExpress 2020计划出炉
    Web UI开发神器—Kendo UI for jQuery数据管理网格编辑操作
    甘特图、Data Editors控件新玩法—DevExpress WPF v19.2
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/C_Language_FromEntryToProjectPractice_IssueAnalysisAndSummary.html
Copyright © 2011-2022 走看看