数据结构以及C语言常问与难点1.序言2.常问与难点,为避免重复发帖,特设此帖并置顶,以供浏览查阅。
3.内容主要是将本版的好帖子收集起来,并加以整理,仅给出知识点分析与问题解答,并不给出原帖链接,致歉。
4.本版中的好东西会慢慢添加进来(各位版主齐心协力,每天添加一个知识点,用不了多久就会很强大),本帖观点只是各位版主和我个人的分析,不一定尽善尽美,但一定是尽心尽力。
各位热心研友如有修正和补充,请在回复中说明。
5.特代表研友感谢各位版主的辛勤奉献,代表版主感谢热心研友对王道的支持(呵呵)。
特别地,祝备考10的研友们一切顺利,考上理想的学校。
珍惜时间,努力才是王道。
1.目录,共占用一个代码区2.3. 1.如下结构体定义的全部细节解释,附有完整程序。
涉及知识点:结构体定义,typedef,指针使用的部分知识。
4.typedef struct LNode{5. ElemType data;6. struct LNode *next;7.} LNode, *LinkList;8.9. 2.符号&的含义,指针进阶。
涉及知识点:引用机制,实参与形参,C语言中地址与指针(以及指向指针的指针),指针的传递(暂不涉及数组与指针的知识,将在以后介绍)。
10.11. 3.如下方式动态分配内存的全部细节解释。
涉及知识点:动态分配内存,define,强制类型转换,malloc(),顺序表存储结构,顺序表与数组,链表结点的内存分配,指针细节,附完整程序。
12.L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));复制代码1.正文,每个问题占用一个代码区复制代码1. 1.如下结构体定义的全部细节解释,附有完整程序。
涉及知识点:结构体定义,typedef,指针使用的部分知识。
2.typedef struct LNode{3. ElemType data;4. struct LNode *next;5.} LNode, *LinkList;6.7.如下是一个最简单的结构体定义:8.struct Node{9. int x,y;10.};11.最后一个分号是不能丢掉的。
这样,上述结构体定义的核心就是12.struct LNode{13. ElemType data;14. struct LNode *next;15.};16.先说ElemType,它并不被编译器识别,完全COPY到程序里肯定是不能执行的。
实际上这只是严书伪代码与读者的一个约定,指元素类型。
在实际编程中,如果我们在程序开头写到 typedef int ElemType; 那我们在程序后面就可以直接使用 ElemType data; 其作用和 int data; 是一样的。
17.typedef相当于我们与编译器的一个约定(windows编程内置了很多这样的约定,只是为了使类型名称更易识记),后面还会有一点关于typedef的解释,如有必要请参阅C语言课本。
18.struct LNode *next;指向本类型的指针,通常在链表中指向另一个结点,在树中指向子树,在图中指向邻结点,等等。
我这样说只是让你能更容易理解指针的作用。
其细节与变化稍后解释。
19.20.这样,其核心已经理解了,下面就用struct{}来代替核心部分。
原结构体定义写成如下形式:21.typedef struct{} LNode, *LinkList;22.这是不是和 typedef int ElemType; 很像,至少有半句 typedef struct{} LNode; 是一样的,其作用正如上文所说,其使用效果稍后提到。
现在我们关心另外半句 typedef struct{} *LinkList; 请看简单的例子,如下:23.typedef int *Pointer;24.实际编程时,定义一个指针,Pointer xx; 与int* xx; 的作用是一样的。
这样就不难理解typedef struct{}*LinkList; 了,这里需要注意的是LNode与LinkList的名称是不能一样的。
25.26.下面是完整的程序以说明结构体如何定义与如何使用,及其变化。
27.#include//************************************************begin28.#include29.30.typedef int ElemType;31.32.typedef struct node{33. ElemType data;34. struct node *next;35.} LNode, *LinkList;36.37.//细心的你可能已经发现,此处我做了更改,将 struct 后面的 LNode 变成了node38.//此处的 node 须与大括号中的struct node *next; 中的node一致,39.//node 与大括号后面的LNode 无需一致,这是因为typedef的作用40.41.//struct node *next; 中的 struct node 不能用LNode 代替,因为编译器42.//检查到 struct node *next; 时还并不知道有 LNode 这个东西。
43.44.int main()45.{46. LNode exp1;47. struct node exp2;48. //这是两种方式是一样的49.50. exp1.data=100;51. exp2.data=200;52.53. LinkList exp3;54. LNode *exp4;55. struct node *exp5;56. //这三种方式是一样的57.58. exp3=(LinkList)malloc(sizeof(LNode));59. exp4=(LNode*)malloc(sizeof(LNode));60. exp5=(struct node*)malloc(sizeof(struct node));61. //为结点分配内存,这一点很重要,以后会作解释62. //这三种写法是一样的63.64. exp3->data=300;65. exp4->data=400;66. exp5->data=500;67. //注意这里是“->”,而不是“.”68.69. exp3->next=exp4;70. exp4->next=exp5;71. exp5->next=NULL;72. //单链表,末尾指针要置空,这一点也很重要73.74. return 0;75.}//***********************************************************end76.77.呵呵,还有一个小经验。
78.typedef struct {79. ElemType data;80.} LNode, *LinkList;81.省略 struct 后面的结构体名称也是可以的,但前提是大括号中不能有指向本类型的指针,至于为什么我就不说啦。
对于比较懒的我可以少打一个单词呢,嘿嘿,这个意义太重大了。
复制代码1. 2.符号&的含义,指针进阶。
涉及知识点:引用机制,实参与形参,C语言中地址与指针(以及指向指针的指针),指针的传递(暂不涉及数组与指针的知识,将在以后介绍)。
2.3.(1)引用机制4.严书里经常看到&,C语言里是地址符,卡住了很多初学者。
对于理解伪代码,把符号&当做C++中的引用符就可以了。
通过下面的例子对引用机制做简单解释。
5.void f_exp(int &x, int y)6.{ x=100;y=100;7.}8.int main()9.{ int a=200,b=200;10. f_exp(a,b);11. printf("%d %d\n",a,b);12. return 0;13.}14.程序输出 100 200 ,这就是符号&在引用机制中的作用。
15.16.(2)形参与实参17.对于函数f_exp()来说,变量x,y都是形参,他们在函数执行完就被释放了,他们的值也就不存在了,x,y可以是任意符合变量命名规则的名称(即使是a和b)来代替,并不影响函数f_exp()的功能。
这对理解指针的传递是有帮助的。
而实参是a和b,他们将值传递给函数f_exp()就完成任务了(如果此处没有使用引用),f_exp()只是接收了a和b 的值,完成一定的功能(可能要返回一些值),这样,实参b并没有被改变,而实参a由于引用机制,在函数f_exp()执行过程中被重新赋值。
18.19.(3)地址和指针20.请看这个简单的例子:21.int main()22.{ int a=1;23. int *p;24. p=&a;25. printf("%d %d\n",a,&a);26. printf("%d %d\n",*p,p);27. return 0;28.}29.此处的&是地址符,a是整型变量,其值是1,&a是a的地址,用整型来输出。
30.这里,p是一个指针,p指向变量a,故*p的值是1。
而p本身的值是什么呢?31.通过程序输出我们可以看到,p本身实际上存储的就是a的地址,整形输出&a和p的值是一样的。
32.33.现在让我们来更进一步:34.int main()35.{ int a=1;36. int *p;37. int **q;38. p=&a;39. q=&p;40. printf("%d %d %d\n",&p,p,a);41. printf("%d %d %d\n",q,*q,**q);42. return 0;43.}44.呵呵,我自己都有点乱了,不要怕,听我慢慢道来。
p是指向变量a的指针,q是指向变量p(我们把指针也当成一个变量,在上一例中我们知道指针p这个变量存储的值是a的地址)的指针,是不是清晰一点了。
上例中我们知道了变量(指针)p的值,那变量(指针)p的地址又是多少呢?从程序输出中我们可以发现,它就是指针q本身所存储的值,更深入一些,我们还可以知道指针q的地址。
45.另外一点,**q,*p,a它们三个的值是一样的,你想明白了吗?46.这个一定要搞明白,明白了这个,指针就明白一半了,下面要讲的指针传递,以后要讲的数组与指针,动态分配数组,就不是那么难理解了。
47.48.(4)指针传递通常与数组联系在一块的,我恐怕越讲越复杂,暂不讲数组,但这样让我很难做啊。