C语言指针二

本文详细解释了C语言中的指针特性,包括const修饰变量和指针的区别,void类型的特殊用法,以及大小端存储的概念。同时介绍了二级指针和如何通过行指针遍历二维数组。
摘要由CSDN通过智能技术生成

指针修饰

1、const常量化

1.1const相当于只读(read-only),被修饰的变量不能被修改,若直接修改则报错

对比:不修改被const修饰的变量,则能输出

a的值不能被更改,但a所在的空间可以修改,也就是通过指针间接修改

const只是修饰变量a,*p没有被修饰,

initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]

警告:a被const修饰,把a的地址赋值给指针时,会丢弃const

1.2const修饰指针指向的内容

const int *p;//const修饰*p,指针指向的内容不能修改,指针的指向可以修改,

int a=2;
int b=20;
const int *p=&a;
//*p=20;//错误,*p被修饰,指针指向内容*p不能修改
p=&b;//p的指向可以被修改

1.3直接修饰p  int *const p;修饰指针的指向p,指针的指向不能修改,可以更改指向的内容。

指针的指向和指针指向的内容都不能修改:

int const * const p;

    1. void空类型

2.1不能修饰变量:void a;//错误

2.2void可以修饰指针

void *p=NULL;//正确写法
int a=2;
(int*)p=&a;//将指针p强制转换成int.在哪使用在哪强转,

    1. 大小端

计算机里如果存储超过一个字节,会出现存储数据的顺序不同的问题,大小端问题。

大端:低地址存放高字节的数据,高地址存放低字节。(左边高字节,右边低字节)

小端:低地址存放低字节的数据,高地址存放高字节。

存储十六进制0x12345678假设起始地址:0x1000

0x1000  0x1001  0x1002  0x1003

   小端:0x78 0x56 0x34 0x12

   大段:0x12 0x34 0x56 0x78

结论:电脑小端存储

4、二级指针:

一级指针:存放变量的地址

二级指针:存放一级指针的地址

格式:存储类型 数据类型 **指针变量名

int **q

int a=2;
int *p=&a;
int **q=&p;

访问a的值:a  *p

访问a的地址:&a  p  *q

访问p的地址:&p  q

p:&p一级指针的地址,一级指针里存的内容是变量的地址

  • 指针与数组

在C语言中,数组的指针是指数组在内存中的起始地址,数组元素的地址是指数组元素在内存中的起始地址

直接访问:通过数组名访问

间接访问:通过指针来访问

地址

内容

元素

p

a

&a[0]

3

a[0]

*a

p[0]

*p

p+1

a+1

&a[1]

4

a[1]

*a+1

p[1]

*p+1

p+2

a+2

&a[2]

5

a[2]

*a+2

p[2]

*p+2

p+3

a+3

&a[3]

6

a[3]

*a+3

p[3]

*p+3

p+4

a+4

&a[4]

7

a[4]

*a+4

p[4]

*p+4

1、一维数组的数组名为一维数组的指针(起始地址)

例:double x[8]; x为x数组的起始地址。

设指针变量px的地址值等于数组指针x(即指针变量px指向数组的首元数)

则:x[i]、p[i]、*(px+i)、*(x+i)、具有完全相同的功能:访问数组第i+1个数组元素。

访问数组元素a[i]的值:

直接访问:a[i]   *(a+i)

间接访问:p[i]   *(p+i)

访问元素a[i]的地址

直接访问:&a[i]   a+i

间接访问:&p[i]   p+i

  1. 注:指针变量和数组在访问数组中元素时,一定条件下其使用方法具有相同的形式,因为指针变量和数组名都是地址量,但指针变量和数组的指针(或叫数组名)在本质上不同,指针变量是地址变量,而数组的指针是地址常量。

a和p本质不同,a是地址常量,p是变量,a不能执行++操作,不能做赋值运算

运算方法:

1)++和*都是单目运算符,优先级相同

2)单目运算符从右向左运算

(*p)++;//先取p指向的内容,对内容++

*p++;//先执行p++,但是++在后,先取*操作,打印*p,再p++,指针向后移动

++*p;//先执行*p,取变量的值,对值进行++;

++(*p);//先执行*p,取变量的值,对值进行++;

*++p;//先对p指向的地址++,对移动后的地址取内容

  • 指针与二维数组

二维数组元素连续存储,按行优先存。

1、使用一级指针遍历二维数组:

a[3][2];//a数组名,第一行首地址,a+1,第二行的首地址。

a[0]

a[0][0]       1

a[0][1]       2

a[1]

a[1][0]       3

a[1][1]       4

a[2]

a[2][0]       5

a[2][1]       6

2、可把二维数组看做由多个一维数组组成

二维数组名代表数组的起始地址,数组名加1,是移动一行元素,

因此,二维数组名常被称为行地址。a[0]、a[1]、

  1. 行地址加*改变性质,按序输出。

*a;表示把行地址降级为列地址。

*a:第一行第一个地址

*a+1:第一行第二例地址 

*(a+1):第二行第一列地址

*(a+1)+1:第二行第二列地址

地址

数组

元素

a[0]

&a[0][0]

*a

1

a[0][0]

*(*a)

*a[0]

a[0]+1

&a[0][1]

*a+1

2

a[0][1]

*(*a+1)

*(a[0]+1)

a[1]

&a[1][0]

*(a+1)

3

a[1][0]

*(*(a+1))

*a[1]

a[1]+1

&a[1][1]

*(a+1)+1

4

a[1][1]

*(*(a+1)+1)

*(a[1]+1)

a[2]

&a[2][0]

*(a+2)

5

a[2][0]

*(*(a+2))

*a[2]

a[2]+1

&a[2][1]

*(a+2)+1

6

a[2][1]

*(*(a+2)+1)

*(a[2]+1)

访问数组元素地址a[i][j]:

a[i]+j &a[i][j] *(a+i)+j;

访问数组元素值:

a[i][j] *(a[i]+j) *(*(a+i)+j)

五、数组指针(行指针)

存储行地址的指针变量叫做行指针变量。形式如下:

<存储类型> <数据类型>(*<指针变量名>)[表达式:列数];

例:int a[2][3]; int(*p)[3];

方括号中的常量表达式表示指针加1,移动几个数据。如:int (*p)[2]指针加一移动两个数据

当用行指针操作二维数组时,表达式一般写成1行的元素个数,即列数

例:使用行指针表示二维数组中的某个元素

例;使用行指针实现二维数组遍历

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

满山的猴子我的腚最红

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值