C语言指针

本文详细介绍了指针在C/C++编程中的基本概念、关键运算符、指针变量的初始化、算术运算、作为函数参数、与数组的关系,以及二级指针、void指针、const指针、数组指针和指针数组的应用,以及二维数组和指针函数的处理方法。
摘要由CSDN通过智能技术生成


一、指针的基本概念

地址:用来区分不同内存字节空间的一个编号
指针:指针就是地址,地址就是指针, 地址是一个编号,指针多了指向的概念

1.指针能够让程序更加简洁
2.指针能够让程序更加高效
3.指针提供了一种间接访问变量的方式

二、指针相关运算符

如果*&同时出现,等价于去掉*&运算符后的结果

1、&

&:获得变量在内存空间中的首地址

注意:
    1.只能对变量&操作
    2.&运算符连接表达式的结果为该变量在内存空间中的首地址
    3.&运算符会让类型升级

2、*

  *:  左值:将右值放入指针指向的空间
       右值:直接取指针对应空间中的值
       
           *p = 100;       //左值
           *p;             //右值
           *(p+1);         //右值
           num = *p;       //右值     
注意:
    1.只能对指针进行 * 操作
    2.*运算符能够让类型降级
    3.对int *       *运算符获得该地址开始向下4字节空间中的值
      对double *    *运算符获得该地址开始向下8字节空间中的值
      对char *      *运算符获得该地址开始向下1字节空间中的值

三、指针变量

数据类型 *变量名;

int *p;
double *p;
char *p;

int* 指向4字节空间, double* 指向8字节空间, char* 指向1字节空间

在64位操作系统中,所有指针均占8个字节

野指针:未经初始化的指针或指向已经被释放过空间的指针

注意:
    不要使用未经初始化的指针

四、指针初始化

int *p = NULL;

NULL:空指针(指向内存地址为0x0的指针)

int num = 100;
int *p = #

int *p = NULL;
p = #

五、指针算术运算

+
-
++
--

++:向内存高地址偏移指向数据类型大小个字节空间
--:向内存低地址偏移指向数据类型大小个字节空间

两个相同类型的指针相减:获得两个地址中间相差了多少个该类型的元素

六、指针常见操作

int a = 100;
int b = 200;
int *p = NULL;
int *q = NULL;

p = &a;
q = &b;

1、 p = &b;
2、*p = b;
3、 p = q;
4、*p = *q;

    1.指针变量本身(p),修改p的值可以改变指针变量的指向
    2.指针变量指向的空间(*p),修改*p的值并不能改变指针变量的指向,只是利用指针修改对应空间中的值

七、指针作为函数参数

1.值传递:
实参将值传递给形参,形参改变,实参不会受影响

函数体内想使用函数体外部变量值的时候使用复制传递(赋值传递)

2.地址传递
实参将地址给形参,形参是实参的指针,可以通过对形参取*改变实参的值

函数体内想修改函数体外部变量值的时候使用地址传递

八、指针和数组

int a[5] = {1, 2, 3, 4, 5};
int *p = NULL;

p = &a[0];
p = a;

数组的数组名是指向数组第一个元素的指针常量
a == &a[0]
int *

访问数组下标为n的元素:
a[n] == *(a+n) == *(p+n) == p[n]

指针[偏移量] == *(指针 + 偏移量)

九、二级指针

指向一级指针变量的指针

int **p;

十、void指针

void *p;                    //所有指针都是8个字节

void * -> int *、char *、double * 不需要强制类型转换
int *、char *、double * -> void * 需要强制类型转换

void * 作为函数参数,可以传入char *、double *、int *的指针,实现一个函数原型下的不同类型指针的传参

十一、const指针

1.const int *p;
2.int const *p;
3.int *const p;
4.const int *const p;
5.int const *const p; 

1和2是等价的
const 修饰 *p, p可以改变, *p不能改变
只能使用指针指向的空间数据,不能修改此数据

3
const 修饰 p, p不可以改变, *p可以改变,一定要初始化,否则该指针为野指针
永远指向某个空间的指针(比如数组的数组名)

4和5是等价的
const 修饰p *p, p不可以改变, *p不可以改变,一定要初始化

十二、数组指针、指针数组

1、数组指针

 数组指针是指针,指针指向整个数组

 数组指针:对一维数组名&,值不变,类型升级为指向整个数组的数组指针
         对数组指针*,值不变,类型降级称为指向数组第一个元素的指针
 int a[5] = {1, 2, 3, 4, 5};

 a可以理解为int * 
 注意:
    在以下两种情况下a不能理解为int *型 
    1.sizeof操作
    2.&操作
        &int *  ==   int ** 
        &a      ==   int (*)[5]

2、指针数组

 指针数组是数组,数组的每个元素都是指针
 int *a[5]:定义一个数组,数组名为a,有5个元素,每个元素为int*型

 char *pstr[5];   

 存放字符串数组用二维数组
 操作字符串数组用指针数组

十三、二维数组和指针关系

int a[2][3] = {1, 2, 3, 4, 5, 6};
int *p = NULL;
int (*q)[3] = NULL;

p = &a[0][0];
p = a[0];
p = *a;
q = a;

二维数组的数组名是指向数组第一行所有元素的一个数组指针

二维数组访问第m行第n列元素:
    a[m][n];
    *(a[m]+n)
    *(*(a+m)+n)
    *(p+m*N+n)
    *(*(q+m)+n)
    *(q[m]+n)
    q[m][n]

1、二维数组传参

二维数组传递数组指针和长度
char str[5][32] = {0};

int fun(char (*pstr)[32], int len);

2、指针数组传参

指针数组传递二级指针和长度
char *pstr[5] = {"hello", "world", "how", "are", "you"};

int fun(char **ppstr, int len);

十四、指针函数和函数指针

1、指针函数

    指针函数是函数,函数的返回值是指针

    注意:
        不能返回局部变量的地址

2、函数指针

    函数指针时指针,指针指向一个函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值