指针
本质:地址
一级指针
一级指针变量名:存储普通变量的地址
格式:存储类型 数据类型 *指针变量名
定义形式:
int a=5;
int *p=&a;
char b=‘q’;
char *p1=&b;
访问:
printf(“%d %d”,a,*p); 输出//5 5
printf(“%p %p”,&a,p); //地址
指针操作符(一定记住这两个运算符含义)
*:取地址里边的内容
&:取地址符:取变量的地址
*&a:===a//&a取地a的地址 *取得a地址中内容,即a &*a:错误//a本身就是内容,无法取地址内的内容
图示:
初始化
指针在使用前要先定义,同时初始化,未初始化的指针变量不能随便使用,会产生野指针
方法
1)int a=5;
int *p=&a; //定义指针的同时,直接初始化
2)int *p=NULL; //先定义一个空指针,后边可以重新赋值
*p
指针p指向变量a,p可以访问到a的值,
可以通过p间接修改变量a的值
指针与一维数组
一维数组:数组名也是数组的首地址,是地址常量,不能为左值(=左边),不能被重新赋值。
指针运算
算术运算
int a[5]={2,13,4,5,6};//char a[]="hello"
int *p=a; //赋给指针p数组a的首地址
printf("%p\n",p); //输出p所含的地址
printf("%d\n",*p); //输出p所含地址中的内容 a[0]
p++;//p=p+1 //指针向高地址方向移动一个数据单位(int 4字节;char 1字节),指针的指向发生改变
printf("%p\n",p); //p++,使p所指地址向高处升一位 p=&a[1]
printf("%d\n",*p); //输出后一位地址所含内容数据即a[1]
.................................................
int a[5]={2,13,4,5,6};
// char a[]="hello";
int *p=a;
printf("%p\n",p);
printf("%p\n",p+2); //指针访问高地址方向第n个元素,指针的指向不发生改变
printf("%p\n",p);
注意
1.p++与p+1的区别:
p++指针向高地址方向移动一个数据单位(int 4字节,char 1字节 不同数据类型不同),指针指向发生改变。
p+1:指针也访问高地址,但指针的指向并没有改变。
2.同一个数组,两个地址之间的差值=相差元素个数(有正负之分)
int a[5];
int *p=a;
int *q=&a[4];
p-q == -4//因为指针p和q之间相差数据类型相同的四个元素 所以差值为-4,反之为4
..................................
printf("%p\n",5);//0x5 %p打印是十六进制地址格式,会把数字5转成十六进制格式
关系运算
同一个数组下比较,才有意义
高地址>低地址
例子:
指针的大小
指针包含内容为地址,但指针也有实际存储地址,存储大小为4字节(系统32位,64位8字节)
(linux)Terminal查询系统位数指令:getconf LONG_BIT 查看操作系统位数
段错误
指针虽然灵活好用但是用不好会出现段错误。
出现的原因有:访问不存在的内存地址、访问系统保护的内存地址 、访问只读的内存地址、空指针废弃 (eg:malloc与free释放后,继续使用) 、堆栈溢出、内存越界 (数组越界)访问不存在的内存地址
注意指针千万不要越界使用
例题:
字符串的倒序输出
#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char a[]="hello world!";
int n=strlen(a);
char *p=a;
char *q=a+n-1;
while(q!=p)
{
putchar(*q);
q--;
}
putchar(*p);
return 0;
}
判断回文数
#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
int a[1000];
int i=0;
while(scanf("%d",&a[i])&&a[i]!=0) //输入0停止输入
i++;
int *p=a;
int *q=a+i-1;
int flag=1;
while(p<=q)
{
if(*p==*q)
{p++;q--;}
else {flag=0;break;}
}
if(flag)printf("是回文数");
else printf("不是回文数");
return 0;
}
指针修饰
const 常量化 read-only //被const修饰后被修饰的元素属性变为仅可读,不可修改