多语言展示
当前在线:905今日阅读:176今日分享:34

C/C++关于指针

一些人可能为认为指针就是一个变量的内容就是加一个变量的地址. 这样认为非常对. 而如果说指针的知识只有这么多, 那么你就大错特错了. 指针并不是你想的那样只是一个变量指向另一个变量, 从而可以改变它的值. 我写这个的目的就是因为网络上有关于这些的好文章太少了. 虽然这篇文章是我自己的理解, 有可能会有一些许错误, 但是我感觉我还是有必要来分享我的理解的.我的这篇文章主要是针对C语言的指针, 所以要学过指针. 明白什么是指针, 二级指针, 数组, 和多维数组与一维数组的关系, 因为下面我对这些知识就不再详细说明了.
工具/原料

学过C指针, 注意是学过, 不是停留在了解, 但也不是掌握(废话, 掌握了你还看这个干啥)

方法/步骤
1

指针如果普通的理解就是一个变量(常变量)的内容就是另一个变量的地址.32位编译器的指针类型其实就是unsigned int而64编译器就是unsigned long int.我在这里用的是VC2013.通过代码cout<

2

‍int i = 10;int *p = &i;void *v = p;p = v;    //错误, 任何类型指针可以赋给void型指针, 但void型指针不能赋给其他任何指针.为什么要void型指针?自我感觉是为了完成一些库函数的任务比如说free的参数, malloc的返回值等等.*v;    错误, 因为它是void型指针, 编译器不知道sizeof(void)是多少. VC2013中的错误信息是: error C2100: 非法的间接寻址同样, v也不能作加减运算如:v += 1, 因为我们不知道void型的大小.

3

不在void型指针上作文章了, 现在开始说说指针的类型. 指针的类型并不是你想的一级指针, 二级指针等. 它其实是有无数种类型的. 光是几级几级的指针就可以是无数种. 但还有别的.指针共分为以下几种大类型:1. 普通指针 typename *name(一级指针, 二级指针等)2. 数组指针 typename name [length](一维数组指针和以与变通指针通用)3. 指向数组的指针 typename (*name)[length](就是在数组指针前面加个&, 它的值与不加&一样)其中, name我没有加黑, 不是因为它不重要, 是因为在作类型的时候它们是不存在的, 只有在定义的时候才要它们.它们之间也是有关系的, 3归属于2, 2又归属于1.为什么这样说?我们知道, 一个一维数组的数组名可以赋给一个指针, 如:int a[10];int *p = a;这样是正确的, 但这样就违背了我上面说的分类了. 因为a算是数组指针, p算是普通指针. 其实p的类型你可以看作是int []类型的. 或者说a的类型可以看作是int *类型的.为什么那个类型要加黑并斜体? 因为, []中间我没写数字, 那么这是为什么? 不写, 说明它中间可以是任何数字. 也就是说, 可以是10, 所以int *p = a是成立的.同样:int a[10][20];int (*b)[20] = a;这样亦是成立的.因为*b可以看作是[]这样int (*b)[20]就可以看作是int b[][20]而[]中间可以是任何数字, 所以这样作成立.那么, 为什么要加那个括号?因为, []的优先级和*不一样[]比*要高.如果不加括号, 它的意思是:建立一个指向int *型的数组, 其长度为20而我们是想让它指向一个元素为10的一维数组, 且这个一维数组的各个元素也是一个长度为20的一维数组为什么这里我没有用建立?因为它在上一行已经建立过了, 这里仅仅是指向它

4

我们知道, 多维数组并不存在, 而是一维数组又套着一维数组.二维数组也是二级指针的一种, 三维数组也是三级指针的一种, 但它们又不是. 因为赋值的时候会报错.如:int i;int *p = &i;int **q = &p;int a[10][20] = {{0}};q = a;  //错误.因为a是int[10][20]型的, 而q是int **型的(也是int [1][1])那么为什么要作这个区别?原因很简单, 因为数组要取值.# define A 10int a[A] = {0};int i = rand() % A;a[i] == *(a+i);      //这一句永远是真.也就是说a[i]永远等价于*(a+i)那么二维数组呢?int a[10][20];a[10]得到的是一个指针, 它不类型不是int *, 而是int[20].为什么要作这个区分?下面的代码看过后, 相信你就知道了.a[i][j];*( *(a+i) + i*j) );这句很乱, 我们先把这些变量的类型说下, a: int[10][20], i: int, j: int.也就是说a是一个二级指针.它加一个*是指针, 再加一个才是有用的数据.所以*(a+i): int [20] (指向数组的指针)  我们把这个表达式执行后的结果用X表示那么:*( X + i*j)的类型就是int型. 类型X是int [20], 也就是个一级指针(上一页的斜黑体字)指针再加个*, 那就是它所指向的数据.

5

上一页的一些知识可能会没看懂, 这里我再说些别的. 这个知识点用我的话说就是: 每一个表达式都有值 为什么?因为:1 + 2+ 3这个表达式再简单不过了, 但其实它和上一页的内容就有关系.1 + 2+ 3, 因为都是+号, 所以优先级一样. 而+的结合顺序是从左到右, 所以先执行1+2, 1+2的结果是3, 所以剩下部分就是3 + 3其中第一个3是1+2的结果, 后面的3是我们代码中的3. 3+3的结果是6, 所以这个语句的结果就是6.而void, 它也是一种类型, 自我感觉它也是占空间的, 应该是1字节, 内容为0.也就是NULL (NULL的定义是# define NULL (void*)0 )

6

然后这里再说说关于字符串(字符指针)为什么我要把这个内容放到这个文章, 并且是最后?因为字符串和我说过的这些知识都有关系.字符串的类型说白了就是字符指针. 为什么?从很多地方都可以得到证明:char *ch = 'abcdefghi';int printf(const char*, ...);还有一点, 学过C++的都可以试试:char ch = 'a';char a[10] = 'bcdefghij';char *p = &a;cout<