<<c 和指针 >> 部分笔记。

最近竟然对指针有些迷惑了,分不清指针的指向。废话少说,复习.(下面内容来自<<c和指针>>)

=指针

==内存和地址

尽管一个字包含了4个字节,它仍然只有一个地址。至于是最左边还是最右边那个字节的位置
,不同机器有不同的规定。

要求边界对其的机器上,整型值储存的起始位置只能是某些特定的字节,通常是2或4的倍数.

==指针变量的内容

& 符号用来产生操作数的内存地址。

==间接访问

通过一个指针访问它所指向的地址的过程成为间接访问或 dereferencing the pointer 
(解引用指针).

==未初始化和非法的指针

指向你猜不到的地方。所以,初始化吧。(这个原文没有)

==NULL 指针

__标准定义了NULL指针__,特殊的指针变量,表示不指向任何东西。

==指针,间接访问和左值

当混用指针和整形值时,__旧式的__编译器并不会发出抱怨。(强制转换吧)

==指针,间接访问和变量

*&a = 25;
这样的代码意味着有人想XX(表现一下的缩略词);

==指针常量

下面这个表达式是__错__的。
*100 = 25; 

下面这个表达式是对的.表示 向地址为 100 的内存赋值 25;
*(int *)100 = 25;

==指针的指针
没什么好说的

==指针的运算

指针加上一个整数的结果是另一个指针。偏移量是指针指向类型的大小.

===算术运算

指针-指针
结果类型是 ptrdiff_t, 有符号整型。两个指针相隔的元素类型大小为单位的长度.
__只有__当两个指针都指向__同一个数组__中的元素,才允许.

大多数编译器不会检查指针表达式结果是否位于合法的边界之内。所以,小心.

===关系运算

<  <=  >  >= ,要求同上.

==总结

声明一个指针变量并不会自动分配任何内存.

==编程提示的总结

如果指针并不指向任何有意义的东西,就把他设置为NULL。

=数组

==一维数组

===数组名

在c中,在几乎所有使用数组名的表达式中,数组名的值是一个__指针常量__,也就是数组
第一个元素的地址.

数组具有一些和指针完全不同的特征。如数组具有确定数量的元素.

只有两种场合下,数组名并不用指针常量来表示,就是当数组名作为 sizeof 操作符或
单目操作符 & 的操作数时.

sizeof 返回整个数组的长度,而不是指向数组的指针的长度.

取数组名的地址所产生的是一个指向数组的指针,而不是指向某个指针常量的指针.

===下标引用

下面的表达式是相同的.
array[subscript]  // a[2]
*(array + (subscript)) // *(a + (2))
subscript[array] // 2[a] 

==指针与下标

===结论

当你根据某个固定数目的增亮在一个数组中移动时,使用时针变量将比使用下标产生效率
更高的代码.

声明为寄存器变量的指针通常比位于静态内存和堆栈中的指针效率更高.

如果你可以通过测试一些已经初始化并经过调整的内容来判断循环是否因该终止,那么你就
不需要使用一个单独的计数器.

那些必须在运行时求值的表达式 如 array+SIZE 往往代价更高.

===数组和指针

声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后在创建数组名
,它的值是一个__常量__.

===作为函数参数的数组名

你现在已经知道数组名的值就是一个指向数组第一个元素的指针,所以很容易明白此时传递给
函数的是一份该指针的拷贝.

==声明数组的参数

下面两个函数原型是相等的

-------------
int strlen(char *string);
int strlen(char string[]);
-------------

==多维数组

===数组名

指向数组的指针这个概念是在相当后期才加入到 K&R C 中的,有些老式的编译器并没有完全实现
它,但是,指向数组的指针这个概念对于理解多维数组的下标引用是至关重要的.

===下标

下面的式子是相等的
*(*(matrix + 1) + 5)
matrix[1][5]

关于 matrix[4, 3] .里面是个逗号表达式阿。就是 matrix[3];

int (*p)[] = matrix;
p 仍然是一个指向整型数组的指针,但数组的长度却不见了。当某个整数与这种类型的指针执行
指针运算时,它的值将根据空数组的长度进行调整(也就是说,与_零_相乘),这很可能不是你所
设想的。有些编译器可以捕捉到这类错误,但有些编译器却不能.

===作为函数参数的多维数组

---------------
int matrix[3][10];

/* 这个是函数的调用形式,后面的是函数定义 */
func2(matrix);

/* 下面两个是正确的 */
void func2(int (*mat)[10]);
void func2(int mat[][10]);

/* 这个是不正确的 */
void func2(int **mat);
---------------

最后一个例子是把 mat 声明为一个指向整型指针的指针,它和指向整型数组的指针并不是一回事。

.....后面的高级部分不写了。发现疑问再整理.
原文地址:https://www.cnblogs.com/playerc/p/c_pointer.html