指针
指针的优点:
1)使程序更简洁、紧凑、高效
2)有效的表达更复杂的数据结构
3) 动态分配内存
4)得到多于一个数的函数返回值
1.指针的基本用法
1.1 指针的概念
内存地址:内存中每个字节单位都有一个编号(一般用十六进制表示)
指针:指针就是内存地址
指针变量:用于存放地址的变量就叫做指针变量
指针变量画图展示:
1.2 格式
存储类型 数据类型 *指针变量名;
int *p; //定义了一个指针变量p,指向的数据是int类型的。
int a = 5;
int *p = &a;
char c=‘v’;
char *q=&c;
printf(“%p %p\n”, p, &a);
printf(“%p %p\n”,q,&c);
printf(“%d %d\n”,a,*p);
printf(“%c %c\n”,c,*q);
访问指针所指向空间的内容用取内容运算符*
那么p变量存放的就是a的地址,q变量存放的是c的地址。
符号*可以访问地址里面的内容。
指针与所指变量之间的关系如下图:
int i=3;
int *i_potinte=&i;
2.3 指针操作符
&:取地址符:取变量的地址
*:取内容符:取地址里面存放的内容
*&a=a;//*和&是互逆运算
&*a//错误(因为运算符优先级)
2.4 指针变量初始化和赋值
指针变量使用前不仅要定义,还要初始化。未初始化的指针变量不能随便使用,不然可能会产生野指针。
(1)将普通变量的地址赋值给指针变量
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a=10;
int *p = &a;//定义的同时赋值
int *q=NULL;//可以初始化为空指针
int *p2;
p2=p;//先定义后赋值
printf("%d %d %d\n",a,*p,*p2);//打印a的值
printf("%p %p %p\n",&a,p,p2); //打印a的地址
*p=20; //同过指向a的指针改变a的值
printf("%d %d %d\n",a,*p,*p2);//打印a的值
printf("%p %p %p\n",&a,p,p2); //打印a的地址
return 0;
}
(2)将数组的首地址赋值给指针变量
char s[10]=“hello”;
char *p = s;
int arr[5]={1,2,3,4,5};
int *q=arr;
printf(“%c\n”,*p);//h
printf(“%d\n”,*q);//1
(3)将指针变量里面保存的地址赋值给另一个指针变量
int a=10;
int *p=&a;
int *q=p;
printf(“%d %d %d\n”,a,*p,*q);
*q=20;//通过指针改变变量a的值
printf(“%d %d %d\n”,a,*p,*q);
p和q都指向了变量a
2.指针运算
2.1 算术运算- +
对指针加减操作其实就是让指针向前向后移动
char str[32]=“hello”;
char *p=str;
printf(“%c\n”,*p);
p++;
printf(“%c\n”,*p);
p–;
printf(“%c\n”,*p);
int *p;p++;//移动4字节
double *q;q++;//移动8字节
p+n:访问高地址方向的第n个数据的地址,指针的指向不发生变化。
p-n:访问低地址方向的第n个数据的地址,指针的指向不发生变化。
偏移了多少字节=n*sizeof(数据类型)
2.2 关系运算 > >= < <= == !=
指针之间的关系运算比较的是它指向地址的高低
指向高地址的指针是大于指向低地址的指针
char s[10]=“hello”;
char *p1=s;
char *p2=&s[2];
if(p2>p1)
printf(“p2>p1”);
else
printf(“p2<p1”);
练习:以下程序打印出来什么
char s[32]=“hello”;
char p=s;
p++;
char y=(–p)++;
printf(“%c”,y); //h
练习:以下程序打印什么结果
int x[] = {10, 20, 30};
int *px = x;
printf(“%d,”, ++*px);//11
printf(“%d\n”, *px); //11
px = x;
printf(“%d,”, (*px)++);//11
printf(“%d\n”, *px);//12
px = x+1;
printf(“%d,”, *px++);//20
printf(“%d\n”, *px);//30
px = x+1;
printf(“%d,”, *++px);//30
printf(“%d\n”, *px);//30
3.指针的大小和段错误
3.1 指针的大小
计算指针大小用:sizeof(指针变量名)
int a=5;
short b=6;
char c=‘a’;
int *p1=&a;
short *p2=&b;
char *p3=&c;
printf(“%d %d %d\n”,sizeof(p1),sizeof(p2),sizeof(p3));//4 4 4 4
总结:
1.32位操作系统指针大小是4字节。64位操作系统,指针大小是8字节。
2.内存地址是固定的,但是变量的地址不是固定的。
3.指针类型根据指针指向的空间的数据类型来匹配