开源项目Tinyhttpd第三篇 由上一篇sizeof引出的对指针和数组的思考

指针和数组,恕我直言,我从17年第一次接触C++语言开始,我就认识这俩玩意儿了。。。。但是我提到指针,就跟见了鬼一样,我记得逼乎上谁说的。。C语言最有特色的部分就是指针了,指针的好处就是灵活。。然而坏处就是太TM灵活了!!用这个东西容易搞出很多莫名其妙的bug和令人非常难懂的语句段来,所以很多高级语言比如C#和Java和前端三大语言虽然都源自于C语言,但是不约而同的没有继承指针这一特性。好的废话不多说,让我们来解析这俩玩意儿吧~~~~

  1. 指针 指针是用来表示或者存储一个存储器地址,这个地址的值直接指向存在该地址的对象的值。指针所占内存单元的大小(即其内容)是跟操作系统的地址位数有关,在32位系统中,指针所占的内存单元就是4个字节,在64位系统中,指针所占的内存单元就是8个字节,在16位系统中,指针所占的内存单元就是2个字节。但是指针所占的内存单元的大小与变量类型无关。
  • 首先事先说明"*“由三个用途,具体如下: 1) 表示乘法(喜闻乐见); 2) 表示定义一个指针变量,用这个符号和普通变量分开; 3) 表示获取指针指向的数据,是一种间接的操作。
int a=10;
int *p=&a;
++*p;//将p所指向的内容加上1后赋值给y,这个语段等价于++(*p)
*p++;//和楼上的方法是一样的,等价于(*p)++,也就是说++和*的优先级一样的

///////////////////////////////////
///////////////////////////////////
int a=0;
int *pa=a;
*&a;//等价于*(&a)表示先取a的地址,然后再取这个地址上的数据,说白了还是a。。。。
&*pa;//等价于&(*pa)表示先取pa指向的数据,也就是a的值嘛,然后再取该数据的地址,说白了还是pa。。。。重要的是分析的过程不是结果哈。。。
  • 关于指针的解析问题(基于32位操作系统)
int num=97;
int *p1=#

假设num的地址为0028FF40,换句话说,p1和p2的值就是0028FF40,都不重要哈,但是指针的类型决定了这个指针指向的内存的字节数并且如何解释这些信息,听起来有点绕口,让我们用这个例子来说吧: num的地址如上述所述是0028FF40,所以p1和p2的解析思路如下:

  • p1:从地址0028FF40开始,p1是int类型的指针,int在上一节说过占四个字节,因此从前往后数上四个字节,将这四个字节的二进制数解析,结果是97;
  • p2:从地址0028FF40开始,p2是char类型的指针,char占一个字节,然后解析这一个字节的二进制数。。结果是a; 从上述可以知道,同样的地址,如果解析的方式不同,得到的数据可是天壤之别,因为就有了一个奇葩的指针:void类型的指针 void指针只是保存了指针的值,没有类型信息,也就是说,你只知道它的地址,但是你并不知道它的解析方式,换句话说你不知道它指向的数据是什么类型的,所以在使用该指针时严禁解引用!!!!!!!,如果非要用它的话必须要将这种指针进行类型转换才能使用!!!!!
  1. 指针和数组(以下叙述基于32位系统) 数组的定义喜闻乐见,就是一个连续占有一段内存单元的变量集合,它的数组名可以看作是一个指针,代表数组的首地址。例子如下:
int a[10];
int *p=a;//和int *p=&a[0]等价,p=p[0]=a[0]=*a,p+i=p[i]=a[i]=*(a+i)
p[n]==*(p+n);
p[n][m]=*(*(p+n)+m);
//sizeof(p)在32位系统中为四个字节。
//sizeof(a)的值为40个字节。在这里数组名a被看作整个数组的代表。
//在上面的p+1并不是指向下一个地址,而是指向下一个元素,在这里要注意哟,这里是有区别的,比如p指向的是int类型的数组首个元素,而p+1大家都知道是指向的是第二个元素,”下一个地址“就是p往后挪了一个字节,“下一个元素”就是p往后挪了四个字节(如果数组是int类型的)或者往后挪了一个字节(如果数组是char类型的)。综上所述,*p是第一个元素的内容,*(p+1)是第二个元素的内容,p+1是第二个元素的地址。
  1. 令人恶心的数组指针和指针数组 这个东西还是很难记住的。。。。还是多看多记吧。。。贼难受呀~~~~
nt *p[10];//指针数组,数组里有十个元素,每个元素都是int型的指针
//[]的优先级比*要搞,p先与[]结合,是一个数组,然后int*修饰数组的内容,所以这是10个指向int类型的指针。
int (*p)[10];//数组指针,()的优先级比[]高,*和p构成一个指针的定义,int修饰的是数组的内容,即是每个元素,数组在这里没有名字,是一个匿名数组,所以p是一个指针,指向了一个匿名的包含int类型的数组。可以理解为int(*)[10]p