文章目录
一、指针与指针变量
1.指针的概念
int a=10;
这行代码定义了一个int类型的变量a,编译器会为该变量分配4个字节的连续存储空间。
若这块连续存储空间的首地址为0x0037FBCC,那么这个变量将会占据0x0037FBCC~0x0037FBD0这个四个字节的空间。
0x0037FBCC就是这个变量的地址,因为通过这个地址就可以找到该变量所在的存储空间,这个地址就是指向该变量的指针。
2.指针变量的定义
指针指示某个变量所在的存储空间,相应指针变量存储这个指针。定义指针变量的语法格式如下:
变量类型* 变量名
变量类型是指针指向数据的类型,变量名前的"*"表示该变量是一个指针
例如:
int *p;//定义一个int* 型的指针变量p
3.指针变量的初始化
指针变量的赋值有两种:
①接收变量的地址为其赋值
int a=10;
int *p;
p=&a;//使int*类型的指针变量p指向int型的变量a所在的存储空间
【注释】&符是取址运算符,作用是获取变量a的地址。
②与其他的指针变量指向同一块存储空间
int *q;
p=q;//使int*类型的指针变量p和q指向同一块存储空间
也可以在定义的同时为指针变量赋值
int a=10;
int* p=&a;//定义一个指针变量p并初始化为变量a的地址
4.指针变量的引用
指针变量的引用就是根据指针变量中存放的地址,访问改地址对应的变量。
访问指针变量中指针所指变量的语法格式如下:
*指针变量
例如:
int a=10;
int * p=&a;
printf("%d\n",*p); //*p就是指针变量p指向的地址中存储的数据
5.空指针、野指针、无类型指针的辨析
空指针:是指没有指向任何一个存储单元的指针。当我们需要用到指针,但不确定指针指向何处时使用。
int* p1=0; //0是唯一不必转换就可以赋值给指针的数据,在ASCII编码中,编号为0的字符就是空
int* p2=NULL; //NULL是一个宏定义,起作用和0相同
在编程时,一般也是先将指针初始化为空,再对其进行赋值操作。
int x=10;
int* p=NULL;//指针指向空
p=&x;
野指针:指向不可用区域的指针。对野指针进行操作可能会发生不可预知的错误。
野指针的形成原因有以下两种:
1)指针变量没有被初始化。定义的指针变量若没有被初始化,则可能指向系统中任意一块存储空间,若指向的存储空间正在使用,当发生调用并执行操作时,就可能造成系统崩溃,因此在定义指针时应使其指向合法的空间。
2)若两个指针指向用一块存储空间,指针与内存使用完毕后,调用相应函数释放了一个指针和其指向的内存,却没有改变另一个指针指向,将其置空。此时未被释放的指针变为野指针。
无类型指针:之前讲述的指针都是确定的类型,如int*,char*型等,但有时指针无法被给出明确的类型定义,此时就用到了无类型指针(void*),这种指针指向一块内存,但因其类型不定,程序无法根据这种定义为该指针指向的变量分配存储空间,所以如果要使用该指针为其他指针赋值,必须先转换成其他类型的指针。使用该指针接收其他指针时不需要强转。
void* p=NULL,*q;
int* m=(int*)p; //将无类型指针p强转成int*类型再赋值
int a=10;
q=&a; //接收其他类型的指针是不用强转
二、指针作为函数参数
在C语言中,只允许由实参传递给形参的单向值传递。这是为什么?
这与C语言中内存的分配方式有关。当发生函数调用时,系统会使用与形参对应的实参为形参赋值,此时的形参以及该函数中的变量都存放在函数调用过程中系统在栈区开辟的空间里,栈区于函数调用时被分配,函数调用结束时被回收,此过程,栈区对主调函数不可见,因此主调函数并不能读取栈中的形参的数据。若要将栈中的数据传递给主调程序,只能通过return实现。
并非所有从主调函数传入的数据都不需要改变,如果需要改变时,使用指针变量作为函数的参数,通过传递地址的方式,使形参和实参都指向主调程序中数据所在地址,从而使被调函数可以对主调函数的数据进行操作。
案例分析:
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
printf("交换函数结果:a=%-5d b=%-5d\n", *a, *b);
}
int main() {
int a = 3, b = 4;
swap(&a, &b);
printf("主函数交换结果:a=%-5d b=%-5d\n", a, b);
}