马兴150809305C语言的指针、链表的原理和各类操作

一、指针

1、运用指针

什么是指针?什么是内存地址?什么叫做指针的取值?指针是一个存储计算机内存地址的变量。从指针指向的内存读取数据称作指针的取值。指针可以指向某些具体类型的变量地址,例如int、long和double。指针也可以是void类型、NULL指针和未初始化指针。

根据出现的位置不同,操作符 * 既可以用来声明一个指针变量,也可以用作指针的取值。当用在声明一个变量时,*表示这里声明了一个指针。其它情况用到*表示指针的取值。&是地址操作符,用来引用一个内存地址。通过在变量名字前使用&操作符,我们可以得到该变量的内存地址。

例如:

#include<stdio.h>

int main()

{

int*ptr;   // 声明一个int指针

int val =1;  // 声明一个int值

ptr =&val;  // 为指针分配一个int值的引用

int deref =*ptr;  // 对指针进行取值,打印存储在指针地址中的内容

printf("deref地址=%ld,值=%d\n",ptr, deref);

第2行,我们通过*操作符声明了一个int指针。接着我们声明了一个int变量并赋值为1。然后我们用int变量的地址初始化我们的int指针。接下来对int指针取值,用变量的内存地址初始化int指针。最终,我们打印输出变量值,内容为1。

第6行的&val是一个引用。在val变量声明并初始化内存之后,通过在变量名之前使用地址操作符&我们可以直接引用变量的内存地址。

第8行,我们再一次使用*操作符来对该指针取值,可直接获得指针指向的内存地址中的数据。由于指针声明的类型是int,所以取到的值是指针指向的内存地址存储的int值。

这里可以把指针、引用和值的关系类比为信封、邮箱地址和房子。一个指针就好像是一个信封,我们可以在上面填写邮寄地址。一个引用(地址)就像是一个邮件地址,它是实际的地址。取值就像是地址对应的房子。我们可以把信封上的地址擦掉,写上另外一个我们想要的地址,但这个行为对房子没有任何影响。

2、指针和数组

C语言的数组表示一段连续的内存空间,用来存储多个特定类型的对象。与之相反,指针用来存储单个内存地址。数组和指针不是同一种结构因此不可以互相转换。而数组变量指向了数组的第一个元素的内存地址。

例如:

#include<stdio.h>

int main()

{

int myarray[4] = {1,2,3,0};

int *ptr = myarray;

printf("ptr地址=%ld,值*ptr=%d\n", ptr,*ptr);

ptr++;

printf("ptr地址=%ld,值*ptr=%d\n", ptr,*ptr);

ptr++;

printf("ptr地址=%ld,值*ptr=%d\n", ptr,*ptr);

ptr++;

printf("ptr地址=%ld,值*ptr=%d\n", ptr,*ptr);

}

总结:
指向指针的指针,可以这样理解,首先指向指针的指针可以把他看成一种特殊的变量,既然是变量就可以存储不同的元素,比如整形变量int a,a可以存储2,3,4这种普通的整型数据,只要将值付给a就行了,但指向指针的指针所存的元素比较特殊,存放的元素一般是存放地址的指针变量,比如我有三个指针变量,int *p1,*p2,*p3,那么我可以定义一个特殊的变量 int **p,我可以将p1的地址付给p,也可以将p2的地址付给p.比如p=&p1,(类似于int a,int *t,t=&a),那么p就代表了他所指向的变量p1或者p2的地址,而p所指向的变量是一个指针变量,*p代表着这个指针变量里面的值(注意值实际上是一个地址),**p代表着它所指向的指针变量的内容(地址)所指向的存储单元的内容(数值)。

二、链表

链表是一种数据结构 ,其最大的的好处就是能够为数据分配动态内存,就不用像一开始那样先为系统分配一个都不知道够不够用的空间来存贮学生的信息。

链表,首先可以细分为一小块一小块的结构体变量,这一小块一小块的结构体变量在链表中是首尾相连的顾名思义 就像一条铁链一样 而这每一小块的结构体变量中又可以从大方向地分成两个部分, 其中一个部分就是——涵盖着该结构体变量里的所有信息,另一个部分就是链接每块结构体变量的部分——指针。

例如:

typedefstruct node
{
char name[20];
struct node *link;
}stud;
这样就定义了一个单链表的结构,其中char name[20]是一个用来存储姓名的字符型数组,指针*link是一个用来存储其直接后继的指针。定义好了链表的结构之后,只要在程序运行的时候在数据域中存储适当的数据,如有后继结点,则把链域指向其直接后继,若没有,则置为NULL。

三、指针和数组的区别

1.声明的区别

指针:exterenint * x;

数组:externint[] y[];

2.指针是保存数据的地址。

数组是保存数据。

3.指针是用于的动态的数据结构。

数组是用于储存固定的数目且数据类型相同的数据结构。

数组一经定义,其基址和大小便固定了,在该数组的有效使用范围内是不可变的;

但是指针则具有很强的动态特征,可以动态地指向任一该类型(定义决定)变量,这也就决定了它有更大的灵活性。

4.数组是开辟一块连续的内存空间,数组本身的标示符代表整个数组。

指针则是只分配一个指针大小的内存,并可把它的值指向某个有效的内存空间。

5.指针是一个变量,可以被赋值,变量的值是另外一个变量的地址。那么,既然指针是变量,那么指针必然有自己的存储空间,只不过是该存储空间内的值是一个地址值,而不是别的内容。

数组名仅仅是一个符号,不是变量,不可以被赋值,它没有自己的存储空间。

6.运算速度上的差异。一般来说,用指针要快些,因为在实际的运算中,总是把数组下标表示通过存储映象函数转换为指针表示,按其地址访问内存,这种转换要进行乘法和加法的运算。

7.数组具有较好的可读性,指针具有更强的灵活性。一般,对某些多维数组中非连续的元素的随机访问用下标表示比较方便,当按递增(减)顺序访问数组时,使用指针快捷而且方便。

8.访问方式:指针是间接访问,首先取得指针的内容作为地址,再去该地址访问数据;

数组是直接访问,数组名即是地址。

四、学生姓名管理系统

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <stdlib.h>

#define N 3

typedef struct node

{

charname[20];

struct node*link;

}stud;

stud * creat(int n) /*建立单链表的函数*/

{

stud*p,*h,*s;

int i;

if((h=(stud*)malloc(sizeof(stud)))==NULL)

{

printf("不能分配内存空间!");

exit(0);

}

h->name[0]=‘\0‘;

h->link=NULL;

p=h;

for(i=0;i<N;i++)

{

if((s=(stud *) malloc(sizeof(stud)))==NULL)

{

printf("不能分配内存空间!");

exit(0);

}

p->link=s;

printf("请输入第%d个人的姓名:",i+1);

scanf("%s",s->name);

s->link=NULL;

p=s;

}

return(h);

}

stud * search(stud *h,char *x) /*查找函数*/

{

stud *p;

char *y;

p=h->link;

while(p!=NULL)

{

y=p->name;

if(strcmp(y,x)==0)

return(p);

elsep=p->link;

}

if(p==NULL)

printf("没有查找到该数据!");

}

stud * search2(stud *h,char*x)

/*另一个查找函数,返回的是上一个查找函数的直接前驱结点的指针,

h为表头指针,x为指向要查找的姓名的指针

其实此函数的算法与上面的查找算法是一样的,只是多了一个指针s,并且s总是指向指针p所指向的结点的直接前驱,

结果返回s即是要查找的结点的前一个结点*/

{

stud *p,*s;

char *y;

p=h->link;

s=h;

while(p!=NULL)

{

y=p->name;

if(strcmp(y,x)==0)

return(s);

else

{

p=p->link;

s=s->link;

}

}

if(p==NULL)

printf("没有查找到该数据!");

}

void insert(stud *p) /*插入函数,在指针p后插入*/

{

charstuname[20];

stud *s; /*指针s是保存新结点地址的*/

if((s= (stud*) malloc(sizeof(stud)))==NULL)

{

printf("不能分配内存空间!");

exit(0);

}

printf("请输入你要插入的人的姓名:");

scanf("%s",stuname);

strcpy(s->name,stuname); /*把指针stuname所指向的数组元素拷贝给新结点的数据域*/

s->link=p->link; /*把新结点的链域指向原来p结点的后继结点*/

p->link=s;/*p结点的链域指向新结点*/

}

void del(stud *x,stud *y) /*删除函数,其中y为要删除的结点的指针,x为要删除的结点的前一个结点的指针*/

{

stud *s;

s=y;

x->link=y->link;

free(s);

}

void print(stud *h)

{

stud *p;

p=h->link;

printf("数据信息为:\n");

while(p!=NULL)

{

printf("%s \n",&*(p->name));

p=p->link;

}

}

void quit()

{

exit(0);

}

void menu(void)

{

system("cls");

printf("\t\t\t单链表C语言实现实例\n");

printf("\t\t|----------------|\n");

printf("\t\t| |\n");

printf("\t\t| [1] 建 立 新 表 |\n");

printf("\t\t| [2] 查 找 数 据 |\n");

printf("\t\t| [3] 插 入 数 据 |\n");

printf("\t\t| [4] 删 除 数 据 |\n");

printf("\t\t| [5] 打 印 数 据 |\n");

printf("\t\t| [6] 退 出 |\n");

printf("\t\t| |\n");

printf("\t\t| 如未建立新表,请先建立! |\n");

printf("\t\t| |\n");

printf("\t\t|----------------|\n");

printf("\t\t 请输入你的选项(1-6):");

}

main()

{

int choose;

stud*head,*searchpoint,*forepoint;

charfullname[20];

while(1)

{

menu();

scanf("%d",&choose);

switch(choose)

{

case 1:

head=creat(N);

break;

case 2:

printf("输入你所要查找的人的姓名:");

scanf("%s",fullname);

searchpoint=search(head,fullname);

printf("你所查找的人的姓名为:%s",*&searchpoint->name);

printf("\n按回车键回到主菜单。");

getchar();getchar();

break;

case 3:printf("输入你要在哪个人后面插入:");

scanf("%s",fullname);

searchpoint=search(head,fullname);

printf("你所查找的人的姓名为:%s",*&searchpoint->name);

insert(searchpoint);

print(head);

printf("\n按回车键回到主菜单。");

getchar();getchar();

break;

case 4:

print(head);

printf("\n输入你所要删除的人的姓名:");

scanf("%s",fullname);

searchpoint=search(head,fullname);

forepoint=search2(head,fullname);

del(forepoint,searchpoint);

break;

case 5:

print(head);

printf("\n按回车键回到主菜单。");

getchar();getchar();

break;

case6:quit();

break;

default:

printf("你输入了非法字符!按回车键回到主菜单。");

system("cls");

menu();

getchar();

}

}

}

时间: 2024-10-19 10:32:45

马兴150809305C语言的指针、链表的原理和各类操作的相关文章

关于C语言的指针、链表的原理和各类操作

今天课上我们老师为我们讲述了c语言的指针.链表的原理以及各类操作. 一.指针 1.指针 指针是一个存储计算机内存地址的变量.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具体类型的变量地址,例如int.long和double.指针也可以是void类型.NULL指针和未初始化指针.指针是一个存储计算机内存地址的变量.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具体类型的变量地址,例如int.long和double.指针也可以是void类型.NULL指针和未初始化指针. 2.数

C语言的指针、链表的原理和各类操作

心得体会: 堂上要讲授许多关于c语言的语法规则,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的.然而要使用c语言这个工具解决实际问题,又必须掌握它.通过多次上机练习,对于语法知识有了感性的认识,加深对它的理解,在理解的基础上就会自然而然地掌握c语言的语法规定.对于一些内容自己认为在课堂上听懂了,但上机实践中会发现原来理解的偏差,这是由于大部分学生是初次接触程序设计,缺乏程序设计的实践所致.学习c语言不能停留在学习它的语法规则,而是利用学到的知识编写c语言程序,解决实际问题.即把c语言作为工

就C语言的指针、链表的原理和各类操作撰写一篇技术博客,说说自己学习C语言指针和链表的体会

一.指向结构体变量的指针变量 指向结构体变量的指针变量的定义形式与一般指针变量的定义形式相同,只是将其指向类型定义为结构体类型即可.例如:        struct person            { charname[20];             char sex;             int age;             float height;            };       struct person *p;则指针变量p,它可以指向struct person类

关于学习C语言的指针、链表的原理和各类操作的体会

要与实际联系起来,链表就想象成一个火车,一个车厢就是一个节点. 总之,要先知道他的原理,原理是最重要的,编程其次 其次,链表得使用较静态数组灵活,因此它对使用者要求也较高,我觉得指针得使用最重要,千万不能乱指,否则很容易发生内存得存取错误,这样得错误较恐怖.

指针、链表的原理和各类操作相关心得以及学生信息管理系统

伴随着学期末的到来,C语言程序设计这门课也接近尾声.经过前两次的教学,我们对C语言也有了深刻的了解,学习的内容也不断的加深.这次我们就学习了C语言程序设计里应用最广泛,也是最难学习的知识--链表和指针的应用. 关于指针和链表这两个的应用和上次的管理系统有着直接的关系,没有添加链表和指针的管理系统无法做到精确的查找.数据存储方面也显得不方便.所以指针和链表的作用能够直接指向你所需要的数据地址,使程序更加完善.这次我就利用指针的应用制作了一个管理员工工资等信息的程序. §1 指向结构体变量的指针变量

C语言复习——指针 链表 与 文件操作

刚刚进入大二,准备开始学习C++,对大一所学的C语言一次练习,正好也是赶上老师布置的任务,用C语言写一个  销售管理系统  ,就尽可能的把所学的都用上,也就是结构,指针,文件操作,还有数据结构,本次加入了链表. 用两个函数 Load_LinkList() 和 Save_LinkList() 让链表与文件操作结合,除了打印函数,其他都是在内存中操作链表,这样写更有条理,在创建链表时没有采用书上的用一个中间变量引导,并插入到结点前面,而是直接在链表尾的next申请内存,便于理解,操作也方便. /*首

黑 马 程 序 员_视频学习总结&lt;c语言&gt;----03 指针

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 一.什么是指针? 用来存放变量地址的变量,就称为"指针变量". 二.指针的定义 一般形式:类名标识符  *指针变量名; int *p; float *q; "*"是一个说明符,用来说明这个变量是个指针变量,是不能省略的,但它不属于变量名的一部分 前面的类型标识符表示指针变量所指向的变量的类型,而且只能指向这种类型的

C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 本文由 arthinking 发表于315 天前 ⁄ itzhai.com原创文章 ⁄ C语言 ⁄ 评论数 3 ⁄ 被围观 1,775 views+ 指针数组: 在一个数组中,如果它的元素全部都是指针类

使用C语言描述静态链表和动态链表

静态链表和动态链表是线性表链式存储结构的两种不同的表示方式. 静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需修改指针,故仍具有链式存储结构的主要优点. 动态链表是相对于静态链表而言的,一般地,在描述线性表的链式存储结构时如果没有特别说明即默认描述的是动态链表. 下面给出它们的简单实现,关于线性表更为详尽的C语言的实现,可以参考 http://www.cnblogs.com/choon/p/3876606.html 静态链表 #define _CRT_SECURE_NO_