目录
段错误:Segmentation fault (core dumped)
概念
指针也就是内存地址,指针变量是用来存放内存地址的变量。
格式
存储类型 数据结构 *指针变量名 例:int *p//定义了一个指针变量p
指针操作符
&:取地址符,获取变量的地址
*:取内容符,获取变量的内容
注:&与*是互逆运算,*&a=a,由于优先级的问题,*只能放在&之前,反之则会报错。
初始化
指针变量在使用前不仅要定义还要初始化,未初始化的指针变量不能随便使用,会产生野指针
将普通变量的地址赋给指针变量
int a=10;
1>int *p=&a;//定义的同时赋值
2>int *p=NULL;//先定义后赋值
p=&a;
将数组的首地址赋值给指针变量
char s[10]="hello";
char *p = s;//指针指向数组首地址,即指向'h'
将指针变量里面保存到地址赋值给另一个指针变量
float a=1.3;
float *p = &a;
float *q = p;
指针运算
算数运算
char s[32]="hello";
char *p = s;
p++;//指针向高地址方向移动一个数据单位,指针指向发生变化
p--;//指针向低地址方向移动一个数据单位,指针指向发生变化
int *p ;p++;//移动4字节
double *p ; p++;//移动8字节
p+n:访问高地址方向第n个数据的地址,指针指向不发生变化
p-n:访问低地址方向第n个数据的地址,指针指向不发生变化
两个地址之间的差 = 两个地址之间相隔元素的个数
关系运算:
指向高地址的指针大于指向低地址的指针(同一个数组中比较)
char s[10]="hello";
char *p1 = &s[1];
char *p2 = &s[3];
p1 < p2;
指针的大小
32位操作系统:指针为4字节。
8位16进制表示 ,4字节。
64位操作系统:指针8字节。
16位16进制表示,8字节。
段错误:Segmentation fault (core dumped)
1.野指针:没有规定指向的指针会在内存中乱指
- 产生原因:
- 指针变量没有初始化
- 指针p被free之后,没有置NULL,会让人以为p是合法指针
解决方法:int *p = NULL;//指针指向空,空指针
2.内存泄漏,对非法空间进赋值
指针修饰
const常量化:const修饰的值不能变,可以通过指针间接修改
const int a=10;
a=20;//错误
int *p=&a;
*p=20;//正确
const int *p:修饰*p,指针指向的内容不能修改,指针的指向可以修改
int a=10;
const int *p=&a;
*p =20;//错误,因为*p被修饰
int b=20;//正确
p=&b;
int * const p:修饰p,指针的指向不能被修改的,指针指向的内容可以修改
int a=10;
int b=20;
int *const p=&a;
*p = 20;//正确
p=&b;//错误,p被const修饰,所以不能修改
大小端
在计算机进行超过1字节数据进行存储时,会出现存储数据顺序不同的情况即大小端存储
大端:在低地址存放高字节数据,高地址存放低字节数据
小端:在低地址存放低字节数据,高地址存放高字节数据
例:存储数据0x12345678
二级指针
二级指针:存放一级指针的地址
格式:存储类型 数据类型 **指针变量名 例:int **p
指针和数组
直接访问:按变量的地址存取变量的值(通过数组名访问)
间接访问:通过存放变量地址的变量去访问变量(通过指针访问)
指针和一维数组
int a[5]={1,2,3,4,5};
int *p = a;
访问数组元素a[i]的值:
直接访问:a[i] *(a+i)
间接访问:p[i] *(p+i)
访问数组元素a[i]的地址:
直接访问:&a[i] a+i
间接访问:&p[i] p+i
a和p本质上不同,a是地址常量,p是变量,a不能执行++操作,但是p可以
指针和二维数组
int a[2][3]={1,2,3,4,5,6};//在a前面加*,表示将行地址降级成为列地址
*a://第一行第一列的地址
*a+1//第一行第二列的地址
*(a+1)//第二行第一列的地址
*(a+1)+1//第二行第二列的地址
访问数组元素地址(a[i][j]的地址)
&a[i][j] *(a+i)+j a[i]+j
访问数组元素值:
a[i][j] *(*(a+i)+j) *(a[i]+j)
数组指针
定义:本质是指针,指向的是数组(又称为行指针)
格式:存储类型 数据类型 ( * 指针变量名) [列数] 例:int (*p)[3];
int a[2][3]={1,2,3,4,5,6};
int (*p)[3] = a;
p可以代替a进行元素访问,但是本质不同
访问a[i][j]地址:
*(p+i)+j p[i]+j
访问a[i][j]内容:
*(*(p+i)+j) *(p[i]+j)
指针数组
定义:本质是数组,里面存放的是指针
格式:存储类型 数据类型 *数组名[元素个数] 例:int *p[3]
1.用于存放普通变量的地址
int a=10,b=20,c=30;
int *p[3]={&a,&b,&c};
访问b的值:
*p[1] *(*(p+1))
访问b的地址;
p[1] *(p+1)
2.用于存放二维数组的每行第一个元素的地址(列地址)
int a[2][3]={1,2,3,4,5,6};
int *p[2]={a[0],a[1]};
访问a[1][2]的值:
*(p[1]+2) *(*(p+1)+2)
访问a[1][2]的地址:
p[1]+2 *(p+1)+2
3.用于存放字符串
char *p[3]={"hello","world","hqyj"};
打印"world"字符串
printf("%s\n",p[1]);
printf("%s\n",*(p+1));
打印’d’这个字符:
printf("%c\n",*(p[1]+4));
printf("%c\n",*(*(p+1)+4));
4.命令行参数
int main(int argc, char const *argv[])
argv:就是一个指针数组,里面存放的是命令行传递的字符串
argc:表示argv指针数组里面存储数据的个数,即命令行传递字符串的个数