C语言指针简介、值传递和址传递浅谈
指针是一种编程语言对象,它存储的是位于计算机内存中的另一个值的内存地址。
从根本上看,指针(pointer)变量是一个值为内存地址的变量(或数据对象)。
内存
内存是电脑上特别重要的存储器,计算机中所有的程序的运行都是在内存中进行的。 所以为了有效地使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1字节。 为了能够有效的访问到内存的每个单元,给内存单元进行了编号,这些单元被称为该内存单元的地址。
将程序运行时的内存简单划分为:
变量都有地址,取出内存中的变量地址代码如下:
#include <stdio.h>
int main()
{
int num = 99;
#//取出num的地址
printf("%p\n",&num);//打印地址;%p为地址打印格式
return 0;
}
地址输出为:
0073FD68
请按任意键继续. . .
间接运算符(解引用运算符):*
假设已知ptr指向val,ptr = #
。 然后使用解引用运算符 * (间接运算符)找出存储在num中的值。
val = *ptr;//找出指向ptr的值
//语句:ptr = #和val = *ptr;放在一起相当于下面的语句:
val = num;
由此可知,使用地址和间接运算符可以间接完成上面这条语句的功能,这也是“间接运算符”名称的由来。
与指针相关的运算符
地址运算符:& 后跟一个变量名时,&给出该变量的地址。例如:&val
表示变量val的地址。
地址运算符:* 后跟一个指针名或地址时,*给出储存在指针指向地址上的值。例如:val = num; val = 22; ptr = &val;/*ptr指向val的地址*/ num = *ptr;/*把ptr指向的地址上的值赋给num*/ //三条语句的结果是:把22赋给了num
指针的声明和使用
#include <stdio.h>
int main()
{
int num = 10;
int * pi = #//pi是指向int类型变量的指针,pi为一个整型指针变量
char * pc;
float * pf;
*pi = 20;
printf("%p\n%p\n",&num,pi);
return 0;
}
类型说明符(int * 、char *、float *等 ),表明了指针所指向对象的类型, 星号,声明的变量是一个指针。int * pi;声明的意思是pi是一个指针,*pi时int类型的。( *和指针名之间的空格可有可无。通常,在声明时使用空格,在解引用变量时省略空格 ) ANSI C专门为指针提供了%p格式的转换说明。
声明指针变量时必须指定指针所指向变量的类型,因为不同的变量类型占用不同的存储空间,一些指针的操作要求知道操作对象的大小。另外,程序必须知道储存在指定地址上的数据类型。
指针变量本身自己也有地址,只是指针变量的值是普通要指向变量的地址。
注意:
1.普通局部变量声明后在栈区开辟空间,栈区的规则是:先使用高地址,后使用低地址。(使用顺序:栈区向下生长,堆区向上生长)
2.数组下标增长,在栈区存储的数组地址是由低到高。
3.基本数据类型都有对应的指针类型。指针的类型和该指针指向的变量类型必须是对应关系。
指针变量大小
#include <stdio.h>
int main()
{
printf("%d\n",sizeof (char *));
printf("%d\n",sizeof (short *));
printf("%d\n",sizeof (int *));
printf("%d\n",sizeof (double *));
return 0;
}
输出:
4
4
4
4
请按任意键继续. . .
值得注意的是,不管是什么类型的指针变量,指针变量的大小只与程序运行平台也就是编译器的位数有关。总结:指针变量在32位平台是4个字节,64位平台是8个字节。
值传递 址传递
C语言传递参数(或者赋值)可以是值传递(pass by value),也可以传递指针(a pointer passed by value),传递指针也叫做址传递。
默认传递值的类型:基本数据类型(整数类型、小数类型、字符类型),结构体,共用体。
默认传递地址的类型:指针、数组。
值传递和址传递的使用特点:
值传递:将变量指向的存储内容在传递/赋值时,拷贝一份给接收变量。(改变接受变量的值,原先变量的值并不改变)
址传递也叫指针传递:如果是指针,就将指针变量存储的地址传递给接受变量,如果是数组,就将数组的首地址传递给接受变量。(通过接收变量的值,可以改变原先变量的值)