《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\n", 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("\n");
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("使用下标访问数组元素\n");
 8    for(i=0;i<2;i++)
 9    {
10    for(j=0;j<3;j++)
11       printf("array[%d][%d]=%d\n",i,j,array[i][j]);
12    }
13    printf("使用数组名访问数组元素\n");
14    for(i=0;i<2;i++)
15    {
16    for(j=0;j<3;j++)
17    printf("array[%d][%d]=%d\n",i,j,*(*(array+i)+j));
18    }
19    printf("使用指针名访问数组元素\n");
20    for(i=0;i<2;i++)
21    {
22    for(j=0;j<3;j++)
23    printf("array[%d][%d]=%d\n",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\n", 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\n", p1, *p1);       /*输出*/
10     printf("p2地址是%d,p2存储的值是%d\n", p2, *p2);       /*输出*/
11     printf("p1-1地址存储的值是%d\n", *(p1 - 1));    /*地址-1后存储的值*/
12     printf("p1地址中的值-1后的值是%d\n", *p1 - 1);    /*值-1后的值*/
13     printf("*(p1-1)的值和*p1-1的值不同\n");
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("\n");
39     quicksort(a,11);
40     for (c=1;c<11;c++)
41         printf("%3d",a[c]);
42     printf("\n  ");
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("\n");
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("排序前:\n");
62     print(l);
63     SelectSort(l);
64     printf("排序后:\n");
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("\n");
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("排序前:\n");
89     print(l);
90     TreeSort(l);
91     printf("排序后:\n");
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趟收集后:\n", i + 1);
146         printl(L);
147         printf("\n");
148     }
149 }
150 
151 void print(SLList L)
152 { /*按数组序号输出静态链表*/
153     int i, j;
154     printf("keynum=%d recnum=%d\n", 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\n", 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域还没赋值):\n");
204     print(l);
205     RadixSort(l);
206     printf("排序后(静态链表):\n");
207     print(l);
208     adr = (int*)malloc((l.recnum)*sizeof(int));
209     Sort(l, adr);
210     Rearrange(l, adr);
211     printf("排序后(重排记录):\n");
212     print(l);
213 }

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

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

 

 

 

 

 

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

posted on 2020-05-02 20:35  Alliswell_WP  阅读(520)  评论(0编辑  收藏  举报

导航