概念:
地址:内存中每个字节都会有的一个编号
指针就是地址
指针变量:用于存放地址的变量
定义格式:
存储类型 数据类型 *指针变量名;
int *p;
int *:表示变量p存放的是一个int类型的地址
指针操作符:
&:取地址
*:取内容,取地址内容 // 后面往往跟着的是地址
*&a==a //&和*互为逆运算
&*a; // 错误,单目运算符,执行顺序是从右向左执行,*a错误,a是变量不是地址
指针初始化:
1. 将普通变量赋值给指针
1.1 int a=20;
int *p=&a;//定义时同时赋值
1.2 int *p;//野指针 乱指向
int *p=NULL;
1.3int b=10;
p=&b;//先定义后赋值
2. 将数组的地址赋值给指针
char s[]="hello";
char *p=s;
3. 将指针变量的值交给另一个指针变量
int a=20;
int *p=&a;
int *q=p;
指针运算
1.算数运算(++ -- + -)
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // a++; ; 错误,a是常量,不能为左值
p++; 等价于 p = p + 1; 指针向高地址方向移动一个数据单位,指针指向会发生改变
p+n:指针向高地址方向访问n个数据单位,指针指向不变
p-n:指针向低地址方向访问n个数据单位,指针指向不变
q-p:两个地址之间相隔数据元素的个数
q和p两者的数据类型相同,q为高地址,p为低地址
最好是在同一个数组下进行
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int arr[5]={1,2,3,4,5};
int *p = arr;
printf("%d %p\n",*p,p); //打印的内容为数组中1和他的地址
p++; //p从指向1变为指向2
printf("%d %p\n",*p,p); //打印的内容为数组中2和他的地址
return 0;
}
2.关系运算(> >= < <= == !=)
用来比较地址的高低
高地址大于低地址
数据类型要相同,在同一存储区域,在同一数组中比较才有意义
指针大小
sizeof(指针变量名); // 指针大小32位操作系统当中:4字节,64位操作系统当中:8字节
指针修饰
const修饰:
const:常量化 read only,可以修饰变量、可以修饰指针,int const a = 10; // const int a = 10;
int const *p; // 修饰 *p 指针指向的内容不能修改,指针指向可以修改
int * const p; // 修饰 p 指针的指向不能修改,指针指向的内容可以修改
const int * const p; // 指针的指向和指针的内容都不能修改
void修饰:
void *p; // 任意类型的指针,一般用在函数的参数以及返回值中,在使用时需要进行强制类型转换
注意:强转只在当前这一条语句生效,对其他语句无效
#include<stdio.h>
int main(int argc, char const *argv[])
{
int a = 1;
void *p = &a;
printf("%d",*(int *)p);//强制转换指针p为int类型
return 0;
}
大小端
小端:在低地址存放低字节数据,在高地址存放高字节数据