指针
一、取地址符号:&
#include<stdio.h>
int main()
{
int a=30;
printf("the %d adress is %p",a,&a);
return 0;
}
the 30 adress is 000000000062FE1C
分析
&是一个单目运算符,用来取一个变量的地址。
%p的作用是打印地址。
地址是指数据在内存中存储位置的编号
二、指针和指针变量
1.指针
指针从本质上来说就是一个内存地址
2.指针变量
指针变量是存放一个内存地址的变量,专门用来存放内存地址,也称为地址变量。
“指针变量”是存放变量所占内存空间“首地址”的变量(因为一个变量通常要占用连续的多个字节空间)。
<1>内存大小
指针也是一种数据类型,通常我们如今的电脑均为64位,指针占8个字节。
#include<stdio.h>
int main()
{
int a;
int *p;//指针变量的初始化
printf("%p\n",p);//输出p的地址
printf("%d",sizeof(p));//利用sizeof()运算符求出指针变量所占8字节
return 0;
}
0000000000000001
8
由此可见,指针变量也是占内存的。
<2>不同类型的指针变量的内存是相同的
#include<stdio.h>
int main()
{
int a;
char b;
float c;
int *p1=&a;
char *p2=&b;
float *p3=&c;
printf("%d\t%d\t%d\t",sizeof(p1),sizeof(p2),sizeof(p3));
return 0;
}
8 8 8
<3>指针初应用
通常为指针的类型变量名=想要让指针变量存储其他变量的地址
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5};
int *p=a;//数组名即为数组首个元素的地址与&a[0]等价
printf("%p\n",p);
printf("%d\n",*p);
p+=1;
printf("%p\n",p);
printf("%d\n",*p);
return 0;
}
输出
000000000062FE00
1
000000000062FE04
2
分析
通过这个符号(解引用),来指向该地址存放的数值,因此输出时p对应的是地址,而p则是指向这个地址所在的数值。
同时对指针变量存储地址进行改变时,不能对*p直接命令操作改变数值,而是应该对p进行命令操作改变地址。
在C语言中,数组元素在内存中的存放顺序是按顺序存放的。
而其中int类型的元素占4个字节由此可见对p+1使得p存放的地址发生了改变,而后原本指向的a[0]转变成a[1]。
3.区别
<1>存放的地址不同
一个变量的地址称为该变量的“指针”,而指针变量是用来存放另一个变量的地址(即指针)。
<2>概念不同
指针是概念,指针变量是具体实现
4.理解
三、野指针和空指针
1.野指针
野指针就是指针指向的位置是不可知的。
通常在指针定义时未进行初始化所导致的。
2.空指针
如果一个指针不指向任何数据,我们就称之为空指针,用NULL表示
定义如下
int *a = NULL;
四、指针函数和函数指针
指针函数
指针函数指的就是返回值为指针的函数,本质就是个函数。
#include<Stdio.h>
int *f(int *a,int len){//定义一个指针函数(返回值为指针)
int i;
for(i=0;i<len;i++){
a[i]=i*2;
}
return a;//数组名为元素首地址
}
int main()
{
int i;
int a[5]={0};
*f(a,5);//调用函数
for(i=0;i<5;i++){
printf("%d\n",a[i]);
}//输出
return 0;
}
函数指针
函数指针指的是指向函数的指针变量,本质就是个指针。
#include<stdio.h>
int f1(int a,int b){
return a+b;
}//求和函数
int f2(int a,int b){
return a-b;
}//求差函数
int main()
{
int (*p)(int a,int b);//定义一个函数指针,指向其形参为连个int型的函数
p=f1;//将f1的地址传给函数指针,即此时的(*p)指向的是求和函数
printf("%d\n",(*p)(1,999));//1+999
p=f2;//将f2的地址传给函数指针,即此时的(*p)指向的是球差函数
printf("%d\n",(*p)(1,999));//1-999
return 0;
}