指针进阶2

怀疑:在取值范围极限处 极大+1就变成极小 极小再-1就变成极大 我怀疑是这样的不知道对不对

数组指针:  数组指针 和 指针数组 是不一样的  数组指针 是一种指针(地址) 指针数组 是数组

1:int arr[10] = {1,2,3,4,5}

arr是数组名 也是数组首元素的地址 数组首元素的地址 不代表整个数组的地址

&arr才是整个数组的地址  老师曾经说过 找到数组首元素的地址 也就能找到数组中其他元素的地址 但是 这些元素所有的地址 都不是整个数组的地址 比方说楼盘 1单元 101室

1单元102室 1单元 103室 1单元104室 1单元201室 1单元202室 1单元203室 这些是数组里所有元素的地址 但是整个数组的地址 是1单元

2:int arr[10] = {1,2,3,4,5};

int* parr[10] = &arr; 这个的意思看优先级 []是第一优先级  *是第三优先级 所以parr优先和[10]结合 代表着这是一个数组 数组10元素 数组的每个元素是int*类型  parr现在是一个指针数组了 这里的*跟int结合了

如果希望parr是一个指针 只能让*和parr首先结合  就必须加() int(*parr)[10]  这样说明parr是一个指针 指针一定有指向 他指向的是数组的10个元素 每个元素的类型是int  此时的parr就是一个数组指针  数组里全是指针 和这个数组的指针  这是两个东西 数组里全是指针 到头来是个数组 数组的指针 到头来 是个指针(地址)

数组里全是地址 就好像地址簿里全是地址 地址簿就是个数组 地址簿存放的地址 比如说放在桌子上 桌子是地址簿的地址 地址簿所放的地址 和地址簿里所存的那些地址 这个不一样

3:double* d[5] 创建一个数组d 里面有5个元素 每个元素是double*的类型

double*(*pd)[5] = &d; 是把数组d的底子好放在了pd里 pd是指针类型 它指向的是数组d d里面的5个元素的类型是double*

&数组名 和 数组名

 

arr是数组首元素的地址

&arr是整个数组的地址

这两个地址位置是一样的 但意义不一样

比方说 我的地址在铁岭 铁岭的地址也在铁岭 那我的地址能和铁岭的地址一样的

比方说 文具店里的笔 和 文具店里第一个柜台里的笔 都在文具店这个地址里 地址一样的 但是意义不一样 你可以说文具店里第一个柜台里的笔 是文具店里的笔 但是你不能说 文具店里的笔 就是文具店里第一个柜台里的笔  这样会造成 以点盖面 以偏盖全 概念混淆

所以说数组首元素的地址 虽然和整个数组的地址 是一样展示的 但是其表达的意义是不一样的 你可以说你是北京人 但你能说北京人就是你一个吗 你可以说你是数组的首元素地址 但你可以说 数组的地址就是你吗

你可以说 北京是中国的首都 但是你可以说中国的首都就是北京吗

其实这些比方 都没有找到一个十分准确的比喻 只能说尽量描绘

数组首元素的地址 就这样写 int* p1 = arr;

整个数组的地址 就这样写 int (*p2)[10] = &arr;

他们的区别是 步长 步长就是1个单位 p1步长是4个字节 就是1个整形 而p2跳过的是1个数组 类型决定了步长 比方说 在印度 卖烟都是一根一根卖 轮根 在我们国家 卖烟最少卖一盒(20支) 甚至有的轮条卖 一条10盒 这个就是步长

一个数组是多少字节呢 就看这个数组里的元素个数 乘以 每个元素的类型空间

 

看 p1和p2 都加1 就能看出来差异了 p1跳过的4个字节 p2跳过的是40个字节 因为p2里有10个p1这么大体积的东西

4:未来如果要去整个数组的地址 需要这样写 &数组 而不是 数组名

5:数组名是首元素地址的两个例外情况  一个是sizeof(数组名) 这个是计算整个数组的体积

再一个就是&数组名  这里的数组名代表整个数组 取出的是数组整个  除了这两个例外以外 数组名都是数组的首元素地址

6:数组指针的使用

int main()

{

 int arr[10] = {1,2,3,4,5,6,7,8,9,10};

int (*pa)[10] = &arr;

int i = 0;

for(i = 0;i < 10;i++)

{

printf("%d",*((*pa)+i));

}

return 0;

}

解释:

int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 这是创建一个有10个元素的数组 数组名是arr 数组里的数的单个体积是int类型 是4个字节

int (*pa)[10] = &arr; 把数组arr的地址取出来 放到pa这个指针变量里 这个变量pa的类型是地址类型  里面10个成员的类型是int

int i = 0; 创建一个整形变量i 我把i的意思理解为"前进" 前进初始值是0 就是从0开始前进

for(i = 0;i < 10;i++) 意思为 循环 i从0开始前进 前进范围是<10 i每次循环前进1步

printf("%d",*((*pa)+i)); 打印 按照%d 10进制有符号数打印 打印","后面的东西

*((*pa)+i))  先看里面的小括号里面的 *pa 表示pa是一个地址类型变量 pa存的是整个数组的地址 也是这个数组第一个元素的地址 (*pa)表示的是这个数组第一个地址 + i 就是从第一个数组的地址 开始"前进" 前进到索引小10 也就是第9个后 得到的是数组里面所有元素的地址  最后外面那一层* 是把这些地址解开 得到地址里面的实际的值

我现在对i的理解 就是"前进"

7:一般情况下 二级指针都用在二维数组以上

8:

void print(int arr[3][5],int r,int c)

{

 int i = 0;

 int j = 0;

 for(i = 0; i < 3; i++)

{

  for(j = 0; j < 5; j++)

{

printf("%d",arr[i][j]);
}

  printf("\n");

}

}

int main()

{

 int arr[3][5]= {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};

print(arr,3,5);

 return 0;

}

解释:

int main()

程序由主函数进入

int arr[3][5]= {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};

创建一个二维数组print(arr,3,5);

调用自定义函数print 传三个参数 arr是数组名 3 是行 5 是列

void print(int arr[3][5],int r,int c)

定义自定义函数 print 传形式参数 形式参数里要写类型

 int i = 0;

 int j = 0;

定义两个变量 i j 初始化为0

for(i = 0; i < 3; i++)

循环 i从0前进 前进范围i < 3 i步进单位是 1

for(j = 0; j < 5; j++)

循环 j从0 前进 前进范围 j<5 步进单位是1

printf("%d",arr[i][j]);

前进后做什么事呢 printf 打印 arr   arr有3行5列 i打印3行 j打印5列

print第二种写法:定义时写的是数组的指针

void print(int(*p)[5],int r,int c)

{

int i = 0;

int j = 0;

for(i = 0; i < r;i++)

{

for(j = 0; j < c; j++)

{

printf("%d",*(*(p + i) + j));

}

printf("\n");

}

}

解释:void print(int(*p)[5],int r,int c)

*p是个地址变量 指向的是一个具有5个元素的地址 这个地址就是首元素地址

*(*(p + i) + j));

p+i就是所有行 前面加* 就是所有行的地址 再加j就是所有行里面所有列的地址

前面再解引用 得到所有行所有列的实际值

9:二维数组的首元素是第一行 二维数组的数组名表示首元素的地址 就是第一行的地址

10:一维数组也是有行有列 只是行为1

11:

int arr[5]  是整形数组

int *parr1[10] parr1是个具有10个元素的数组 每一个元素的类型是 int*

int (*parr2)[10]  parr2是一个指针 指向的是一个数组的10个元素  每个元素的类型是int

int(*parr3[10])[5] parr3[10]是一个具有10个元素的数组 它的类型是* 指向的是一个数组的5个元素

12:一个具有10个元素的数组 和一个数组的10个元素 是不一样的概念

13:把数组名和[]去掉 就是成员的类型

14:int(*parr3[10])[5]

parr3是个数组名 有10个元素  把parr3[]去掉 剩下的指针 剩下的这个东西 是一个指针

指针指向的一个数组 数组是5个元素 每个元素是int 这个数组的每个元素是一个数组指针

数组指针也是一种指针 把这种指针再存到一个数组里面去 parr3是一个数组 数组10个元素 每个元素是一个数组指针

parr3是一个存放数组指针的一个数组 该数组能够存放10个数组指针 每个数组指针 能够指向一个数组 数组5个元素 每个元素是int

数组参数 指针参数

1:一个函数的参数 可以是数组 也可以是指针

2:二维数组传参 不可以省略列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值