• Home
  • About
    • Road to Coding photo

      Road to Coding

      只要那一抹笑容尚存, 我便心无旁骛

    • Learn More
    • Email
    • Github
  • Posts
    • All Posts
    • All Tags

一个C语言指针的问题让我翻车

28 Jul 2018

现在真的是水的不行.一天天的,混不下去了,以后还是转业算了,当个肥宅最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



Share Tweet +1