您好,登录后才能下订单哦!
指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; 能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。指针极大地丰富了C语言的功能。 学习指针是学习C语言中最重要的一环, 能否正确理解和使用指针是我们是否掌握C语言的一个标志。同时, 指针也是C语言中最为困难的一部分,在学习中除了要正确理解基本概念,还必须要多编程,上机调试。只要作到这些,指针也是不难掌握的。
指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。 一般把存储器中的一个字节称为一个内存单元, 不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等, 在第二章中已有详细的介绍。为了正确地访问这些内存单元, 必须为每个内存单元编上号。 根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址。 既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。 内存单元的指针和内存单元的内容是两个不同的概念。 可以用一个通俗的例子来说明它们之间的关系。我们到银行去存取款时, 银行工作人员将根据我们的帐号去找我们的存款单, 找到之后在存单上写入存款、取款的金额。在这里,帐号就是存单的指针, 存款数是存单的内容。对于一个内存单元来说,单元的地址即为指针, 其中存放的数据才是该单元的内容。在C语言中, 允许用一个变量来存放指针,这种变量称为指针变量。因此, 一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针。图中,设有字符变量C,其内容为“K”(ASCII码为十进制数 75),C占用了011A号单元(地址用十六进数表示)。设有指针变量P,内容为011A, 这种情况我们称为P指向变量C,或说P是指向变量C的指针。 严格地说,一个指针是一个地址, 是一个常量。而一个指针变量却可以被赋予不同的指针值,是变。 但在常把指针变量简称为指针。为了避免混淆,我们中约定:“指针”是指地址, 是常量,“指针变量”是指取值为地址的变量。 定义指针的目的是为了通过指针去访问内存单元。
既然指针变量的值是一个地址, 那么这个地址不仅可以是变量的地址, 也可以是其它数据结构的地址。在一个指针变量中存放一
个数组或一个函数的首地址有何意义呢? 因为数组或函数都是连续存放的。通过访问指针变量取得了数组或函数的首地址, 也就找到了该数组或函数。这样一来, 凡是出现数组,函数的地方都可以用一个指针变量来表示, 只要该指针变量中赋予数组或函数的首地址即可。这样做, 将会使程序的概念十分清楚,程序本身也精练,高效。在C语言中, 一种数据类型或数据结构往往都占有一组连续的内存单元。 用“地址”这个概念并不能很好地描述一种数据类型或数据结构, 而“指针”虽然实际上也是一个地址,但它却是一个数据结构的首地址, 它是“指向”一个数据结构的,因而概念更为清楚,表示更为明确。 这也是引入“指针”概念的一个重要原因。
文件型指针
#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值。
指针与数组
#include<stdio.h>
int main()
{
intmyarray[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);
}
C语言的数组表示一段连续的内存空间,用来存储多个特定类型的对象。与之相反,指针用来存储单个内存地址。数组和指针不是同一种结构因此不可以互相转换。而数组变量指向了数组的第一个元素的内存地址。
一个数组变量是一个常量。即使指针变量指向同样的地址或者一个不同的数组,也不能把指针赋值给数组变量。也不可以将一个数组变量赋值给另一个数组。然而,可以把一个数组变量赋值给指针,这一点似乎让人感到费解。把数组变量赋值给指针时,实际上是把指向数组第一个元素的地址赋给指针。
指针与结构体
#include<stdio.h>
struct person {
intage;
char *name;
};
int main()
{
struct person first;
struct person *ptr;
first.age = 21;
char *fullname = "full name";
first.name = fullname;
ptr= &first;
printf("age=%d, name=%s\n", first.age, ptr->name);
}
#include<stdio.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
main()
{
int count,*array; /*count是一个计数器,array是一个整型指针,也可以理解为指向一个整型数组的首地址*/
if((array=(int *) malloc(10*sizeof(int)))==NULL)
{
printf("不能成功分配存储空间。");
exit(1);
}
for (count=0;count<10;count++) /*给数组赋值*/
array[count]=count;
for(count=0;count<10;count++) /*打印数组元素*/
printf("%d-",array[count]);
}
上例中动态分配了10个整型存储区域,然后进行赋值并打印。例中if((array=(int *) malloc(10*sizeof(int)))==NULL)语句可以分为以下几步:
1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针
2)把此整型指针地址赋给array
3)检测返回值是否为NULL
2、free函数
由于内存区域总是有限的,不能不限制地分配下去,而且一个程序要尽量节省资源,所以当所分配的内存区域不用时,就要释放它,以便其它的变量或者程序使用。这时我们就要用到free函数。
其函数原型是:
void free(void *p)
作用是释放指针p所指向的内存区。
其参数p必须是先前调用malloc函数或calloc函数(另一个动态分配存储区域的函数)时返回的指针。给free函数传递其它的值很可能造成死机或其它灾难性的后果。
注意:这里重要的是指针的值,而不是用来申请动态内存的指针本身。例:
int *p1,*p2;
p1=malloc(10*sizeof(int));
p2=p1;
……
free(p1) /*或者free(p2)*/
malloc返回值赋给p1,又把p1的值赋给p2,所以此时p1,p2都可作为free函数的参数。
malloc函数是对存储区域进行分配的。
free函数是释放已经不用的内存区域的。
malloc函数
malloc函数的原型为:
void *malloc (unsigned int size)
其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号×××数,返回值是一个指向所分配的连续存储域的起始地址的指针。还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
心得体会:
堂上要讲授许多关于c语言的语法规则,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的。然而要使用c语言这个工具解决实际问题,又必须掌握它。通过多次上机练习,对于语法知识有了感性的认识,加深对它的理解,在理解的基础上就会自然而然地掌握c语言的语法规定。对于一些内容自己认为在课堂上听懂了,但上机实践中会发现原来(转载自第。)理解的偏差,这是由于大部分学生是初次接触程序设计,缺乏程序设计的实践所致。
学习c语言不能停留在学习它的语法规则,而是利用学到的知识编写c语言程序,解决实际问题。即把c语言作为工具,描述解决实际问题的步骤,由计算机帮助我们解题。只有通过上机才能检验自己是否掌握c语言、自己编写的程序是否能够正确地解题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。