现在真的是水的不行.一天天的,混不下去了,以后还是转业算了,当个肥宅最TM开心了
起因是小伙伴问了我一个需求实现: 函数中分配二维数组,返回值又已经被使用.
那么,自然而然就是指针的指针了,传参数三维指针(不然改个锤子)
以往的代码实现:
#include <stdio.h>
#include <stdlib.h>
char **foo(char **p, int m, int n)
{
foo = (char **)malloc(sizeof(char *) * sizeof(m));
for (int i = 0; i < n; ++i)
p[i] = (char *)malloc(sizeof(char) * n);
// *(p + i) = (char *)malloc(sizeof(char) * n);
}
上面是一般的二维数组的分配实现.
改用指针的指针传递,实际上至需要修改其中几个小地方就好了
#include <stdio.h>
#include <stdlib.h>
void foo(char ***p, int m, int n)
{
(*p) = (char **)malloc(sizeof(char *) * sizeof(m));
for (int i = 0; i < n; ++i)
(*p)[i] = (char *)malloc(sizeof(char) * n);
}
那么问题来了,不使用数组下标语法糖的形式,使用原生指针怎么写?
*(*p + i) = (char *)malloc(sizeof(char) * n);
而之前的错误形式是这样的:
(**p + i) = .... // x
究其本质,还是自大,不扎实.
不过想了一下,主要是这些没考虑到:
-
简便写法
(*p)[i]
, 没错,这样解引用就和原来一样了 -
为什么可以写成
*(*p + i)
?
同理,想想之前的下标语法糖, 这里只不过解引用了一下,还原为二维指针,然后进行移动
到了其他的位置, 当然是一个维度中,也就是int a[m][n]
,m层次上的移动.从(*p)[0][n]到
(*p)[1][n], 之后解引用不就是对应一维指针,(指向字符串的),然后该咋来咋来,该咋用咋用.
这其中有一个很重要的点: 数组名就是数组首元素地址,进行与整型的计算时,就是数组元素移动
我特么把*(*p + i)
和*(&(*p) + i)
混淆了,后面的才是下一个指向二维数组的指针
arr[index] = *(arr + index)
这么简单的问题都凉了,GG算了
- 为什么不能写
(**p + i)
为什么,这到是个锤子! (char **)p => (char) **p
,此时加上整型的计算结果,是整型.
我们要获取可使用的指针,或去糖之后,都是有解引用的,这个简直不能看.而且此时(**p) => char *
内存并没有分配,是未定义的值,求得的结果是nil + index的值..
- 另外再扯一点
事实上, 分清数组和指针,多看两眼
char *str = "hello world"; // str中保存了字符串字面量的地址
char sstr[100] = "..."; // sstr中存的就是值,sstr地址值与sstr[0]一致
好了,就说这么多吧.后面的自己在想想就好了.
有兴趣了,看看这几个就可以了:
int a[12];
a[1]; // *(a + 1)
&a; // value: &a == &a[0]; &a + 1 == &a[0] + sizeof(int) * array_length;
&a+1; // &a[0] + sizeof(int) * array_length
*(a+1); // a[1], a=> &a[0], *(&a[0] + 1) = a[1]
(int *)(&a + 1)[-1]; //a[12];
PS: 今天看到了很多牛皮的博客,牛皮的人怎么这么多,我有想了想我,唉,垃圾一个,脑子疼
我觉得,以后不能再把心情这种写在技术总结里面了,太消极,别人看见也不好
而且,我文笔并不好啊,就是个看漫画,打游戏的死肥宅.
如果有机会了,准备写写漫画或者游戏的简评,
再说吧,太远了,还是先弄好C++了.(逃
July 28, 2018 11:41 AM