指针是C语言的灵魂
1.指针的定义
地址:地址就是内存单元的编号,它是从零开始的非负整数。
指针:指针就是地址,地址就是指针。
指针变量是存放内存单元地址的变量。
指针的本质是一个操作受限(指针只能在某些情况下相减,不能进行加乘除等操作)的非负整数。
下面我们将通过一个简单的C程序来简单介绍一下指针:
#include<stdio.h>
int main(void)
{
int *p; //p是个变量名字,int*表示该p变量只能存储int类型变量的地址
int i = 10;
int j;
//p初始为一个随机值,指向不确定的单元,故不能直接printf,会报错
p = &i;
j = *p; //等价于 j = i;
printf("i = %d, j = %d, *p = %d\n", i, j, *p);
return 0;
}
接下来,我们将通过一个实例,即“如何通过被调函数来修改主调函数中变量i的值”来进一步了解指针。
# include<stdio.h>
void f(int * p) //不是定义了一个名字叫做*p的形参,而是定义了一个形参,该形参名字叫做p,它的类型是int*类型
{
*p = 100;
}
int main(void)
{
int i = 9;
f(&i);
printf("i = %d\n", i);
return 0;
}
结合上述代码块,我们总结通过被调函数来修改主调函数中变量i的值一共需要三个步骤,也是三个关键点:
①.实参为相关变量的地址;
②.形参为以该变量的类型为类型的指针变量;
③.在被调函数中通过 *形参变量名 的方式就可以修改主函数中的普通变量i的值。
2.指针和一维数组
数组名:
一维数组名是个指针常量,它存放的是一维数组第一个元素的地址,同时它的值是不能被改变的。一维数组名指向的是数组的第一个元素。
下标和指针的关系:
a[i] <<===>> *(a+i) (等价写法)
假设指针变量的名字为p,则p+i的值是p+i*(p所指向的变量所占的字节数)。
所有的指针变量都是只占4个字节,用第一个字节的地址表示整个变量的地址。
接下来,我们通过一个实例“通过被调函数打印数组的所有值”来进一步理解指针和一维数组的关系,以及使用方法:
// 通过被调函数打印数组的所有值
# include<stdio.h>
void Show_Array(int * p, int len) //若访问一维数组只需要知道数组的第一个元素地址以及数组的长度即可
{
p[2] = -1; //p[0]=*p, p[2]== *(p+2)==*(a+2)==a[2]; p[i]就是主函数的a[i]
int i = 0;
for(i=0; i<len; ++i)
printf("%d\n", p[i]);
}
int main(void)
{
int a[5] = {1,2,3,4,5};
Show_Array(a,5); //a等价于&a[0],&a[0]本身就是int *类型
return 0;
}