c语言学习分享初级指针(C语言学习指针的介绍)
c语言学习分享初级指针(C语言学习指针的介绍)程序是由数据和指令组成的,而数据和指令在执行过程中是存储在计算机内存中的,变量是程序数据中的一种,因此变量也存储在内存中。指针的概述2.指针为C语言的内存动态分配系统提供支持3.指针为动态数据结构(如链表、队列、二叉树等)提供支持4.指针可以改善某些子程序的效率
指针是C语言提供的一种特殊而又有非常重要的数据类型。
联合使用指针和结构体这两种数据类型可以有效地表示许多复杂的数据结构,如队列、堆栈、链表、树、图等。
指针这个内容为什么那么的重要?
1.指针为函数提供修改变量值的手段
2.指针为C语言的内存动态分配系统提供支持
3.指针为动态数据结构(如链表、队列、二叉树等)提供支持
4.指针可以改善某些子程序的效率
指针的概述
程序是由数据和指令组成的,而数据和指令在执行过程中是存储在计算机内存中的,变量是程序数据中的一种,因此变量也存储在内存中。
内存地址:内存中的每字节都有一个唯一的编号,以便内存的管理。
内存地址的编码方式与操作系统有关,在32为计算机上,内存地址编码是32位,从0x00000000到0xFFFFFFFF,最多支持4G的内存。任何数据存储到内存中的过程,都需要记录两条信息,一是分配的内存空间的首地址,二是分配的内存空间大小。
如果变量的值已经存储与内存中,对变量的访问有两种方式:直接寻址和间接寻址
直接寻址,顾名思义就是直接访问变量的值,使用变量名或使用变量的地址都可直接引用变量的值。
例如:
short int a=12;
假设编译器在编译程序时为短整型变量分配了两个字节的存储单元。如图
直接寻址示意图
由于程序运行时变量a被初始化为12,因此变量a当前值是12,也可用变量名a表示变量的值。这种直接按变量名来存取变量值访问方式。而用地址访问就必须知道变量的地址,需要使用取地址运算符&来获取变量的地址。
例如,用&a表示变量a在内存中所占存储单元的首地址,而无须关心该地址的具体值是多少。如果通过p=&a赋值操作,将变量a的地址赋值给另一个变量p,那么我们就获得了另外一种访问变量的方法,即通过先访问变量p获得变量a的地址值,然后再到该地址值代表的存储单元中去访问变量a。当然,这里的变量p不是普通类型的变量,它是一种特殊类型的变量,即指针类型的变量,简称指针变量。
指针变量是C语言中专门用于存放地址型数据的变量。这种通过指针变量间接存取它所指向的访问方式,称为间接寻址。间接寻址是通过其他变量来获取要访问变量的地址,再进行访问。
间接寻址示意图
C语言提供了两个单目运算符&和*,使用它们可以方便地实现有关地址和指针的运算。
取地址运算符&用于得到变量的地址。
p=&a;
当指针变量p中存储了变量a的地址时,我们就称指针变量p指向了变量a。在32位计算机上,由于地址是32位的,因此要用指针变量保存地址就需要占用4字节的存储空间。
为了得到一个指针所指对象的内容,可以用*运算符放在指针变量前实现通过指针变量间接访问它所指向的存储单元的目的,*称为指针运算符,也称间接寻址运算符或解引用运算符,它返回其操作数(即一个指针)所指向的对象的值。
假设指针变量p已指向了变量a,那么通过*p也可以得到指针变量p所指向的变量a的值,输出*p的值和输出a的值是等价的。
以这种方式使用指针运算符*,称为指针的解引用。对指针变量进行解引用时,要求指针已被正确初始化或已确认它已指向某个确定的内存单元。
如果一个指针变量没有被初始化,就使其指向内存中某个确定的存储单元,对这个指针变量解引用,将引起一个致命的运行时错误,或者意外地改写内存中的重要数据,使程序得到一个错误的运行结果。
编程小实例:
从键盘任意输入两个整数
#include<stdio.h>
void swap(int x int b);
int main()
{
int a b;
printf("Please enter a and b:");
scanf("%d %d" &a &b);
printf("Before swap:a=%d b=%d\n" a b);
swap(a b);
printf("After swap:a=%d b=%d\n" a b);
return 0;
}
void swap(int x int y)
{
int temp;
temp=a;
a=b;
b=temp;
}
程序运行的结果如下:
Please enter a and b:36 12(按回车)
Before swap:a=36 b=12
After swap:a=36 b=12
程序运行示意图如下
由于形参x和y是动态局部变量,离开定义它们的函数swap后,分配给它们的存储空间就被释放了,当然保存在变量x和y中的互换结果也就找不到了。这时,主函数中实参a和b的值却为发生任何的改变,仍然保持原来的值,即a=36,b=12,因此,程序执行第二个printf的输出结果就是“After swap:a=36 b=12”。显然swap毫无做功。
由于C语言中函数参数的传递方式是“单向传值”,当用简单变量作为函数实参进行函数调用时,由于实参向形参的传值是单向的,实参的值被复制个形参后,对形参值得任何改变都不会影响主函数中对应的实参值,因此,为了在函数调用后得到修改后的参数值,虽然可以利用return语句将其值从被调函数中返回给主函数,但return仅限于从函数返回一个值,但需要得到两个或多个修改了的值时,就要用传地址值得方法。
一种方法是用数组名作为函数参数,即将数组在内存中的起始地址传给形参,这样做可以得到多个变化的值。这些变化的值存放在实参数组中,它是通过形参数组将其改变的。
如果待修改的数据不多,且不是放在一个数组中,那么可以用指针变量作为函数参数。由于指针变量中存放的某个变量的地址,因此它传给形参的是指针所指向的变量所占存储单元的地址,即不是直接复制变量的值给形参,而是复制了变量地址给形参,相当于房主配了一把钥匙给房客,房客在得到房间钥匙的同时也获得了修改房间内容的权限。由于实参和形参都表示同一个地址值,相当于它们都指向了同一个内存单元,因此,在这种情况下,被调函数对形参所指向的存储单元值的任何修改,都可以在主函数中通过相应的实参来间接读取。