-
An array name is the address of the array's first element. If
demois an array, thendemo==&demo[0]holds true -
%pis the conversion specification for displaying a pointer in hexadecimal -
%zdis the conversion specification for the return value ofsizeof(that is, thesize_ttype), measured in bytes. -
In the
clanguage, the two expressionsar[i]and*(ar + i)are equivalent, but there is one point: only whenaris a pointer variable can an expression such asar++be used. -
The difference between addresses can use the conversion specification
%td
Pointer Operations
1.赋值:把地址赋给指针
- 数组名赋值
- 带地址运算符&的变量名赋值
- 另一个指针赋值
2.解引用:*运算符给出指针指向地址上的值
3.取址:&运算符给出变量本身的地址
4.指针与整数相加:可以使用 + 把指针与整数相加,或者整数与指针相加。
- 计算结果 = 整数 × 指针所指向类型的大小(以字节为单位)+ 初始地址
5.递增指针:递增指向数组元素的指针可以让该指针指向数组的下一个元素。
6.指针减去一个整数:可以用 - 从指针减去一个整数,这里指针必须在被减数的位置。
- 计算结果 = 初始地址 - 整数 × 指针所指向类型的大小(以字节为单位)
7.递减指针:递减指向数组元素的指针可以让该指针指向数组的上一个元素。
8.指针求差:可以计算两个指针之间的差值。差值的单位与数组类型的单位相同,例如 int 类型的数组中两个相邻的值的指针相减,那么得出的值为 1,即 1 个int。
9.比较:可以用关系运算符比较两个指针的值,前提是两个指针指向相同类型的对象。
The const Keyword
# 以下为2021.10.28日的笔记
作用:用于限制一个变量为只读变量。
- 编写一个处理基本类型的函数时,对于数组来说,必须传递指针,这样效率高,但是会面临一个问题就是关于修改数组的问题。解决办法是通过使用指向const的指针,表明该函数不会通过指针来修改数据,如下:
int sum(const int ar[], int n); /* 函数原型 */
int sum(const int ar[], int n) /* 函数定义 */
{
int total = 0;
...
return total
}
- const可以创建const数组、const指针、指向const的指针。
# 说说const指针和指向const的指针
const double locked[4] = {1, 2, 3, 4}
const double * pc = rates; /* 指向const的指针 */
double * const pc = rates; /* const指针 */
const double * const pc = rates;
- 规律总结:
1.*左边有const意味着是指向const的指针,特点是不能使用指针来更改它所指向的值。
2.*右边有const意味着是const指针,特点是指针本身的值是不可变的。即指针指向的地址是一个固定值,那就不能改变指针所指向的地址。
3.如果const用了两次,则不能使用指针改变指向的值且指针指向的地址也不能变。
4.指向const的指针可以指向const数据和非const数据,但是普通指针不能指向const数据(不然就能通过指针操作const数据了)
# 用途:
- 指向const的指针通常用于函数形参中,表明该函数不会使用指针改变数据。
Pointers and Multidimensional Arrays
I feel completely lost reading the book, but I must understand this! There are more impatient people in the world, so stay patient and I will definitely figure it out!
int zippo[4][2]; /*内含int数组的数组*/
// zippo是数组首元素的地址,即zippo == &zippo[0];
// 而zippo[0]是一个内含两个int对象的数组,所以zippo[0] == &zippo[0][0];
// 所以zippo是一个指向占用两个int大小对象的指针,而zippo[0]是一个指向占用1个int大小对象的指针
// 但是由于zippo和zippo[0]开始于同一个地址,所以zippo == zippo[0]
// 解引用一个指针(即在指针前使用 * 运算符),得到指针所指向的地址上的值。因为zippo[0]是数组首元素zippo[0][0]的地址,所以*(zippo[0]) = zippo[0][0].
// *zippo = zippo[0],因为zippo[0] == &zippo[0][0],所以*zippo = &zippo[0][0]
// **zippo = zippo[0][0]
- For
intzippo[4][2], the relationships are summarized below:
# 几类符号:
1.zippo
2.zippo[0]
3.&zippo[0]
4.zippo[0][0]
5.&zippo[0][0]
6.*zippo
7.**zippo
(1) zippo数组名代表二维数组首元素的地址,所以推导出 zippo == &zippo[0],所以 *zippo = zippo[0]
(2) 二维数组首元素是一个包含两个int对象的一维数组,所以zippo[0]相当于一维数组数组名,那么针对一维数组数组名来说,数组名相当于首元素的地址,所以推导出 zippo[0] == &zippo[0][0], 所以 *zippo[0] = zippo[0][0]
结合(1)和(2),可以推导出 **zippo = zippo[0][0]
先背下来吧,zippo == zippo[0] == &zippo[0][0]
- 注意:zippo + 1 得到的值和 zippo[0] + 1 得到的值是不同的,因为zippo是指向一维数组对象的指针,而 zippo[0] 是指向一维数组的单个对象的指针。两个对象占用的内存空间大小不同。
Pointers to Multidimensional Arrays
// pz 指向一个内含两个int类型值的数组
int (* pz)[2]; // 括号的原因是[]的优先级高于*
// 下面是声明一个指针数组
int * pz[2] // 表示该数组含两个指向int类型值的指针
Functions and Multidimensional Arrays
# 用到时再说
Variable-Length Arrays
变长数组指在创建数组的时候,可以使用变量指定数组的维度。
# 声明带二维变长数组参数的函数如下:
int sum2d(int rows, int cols, int ar[rows][cols]); # 注意:rows和cols的声明要在ar[rows][cols]之前,因为ar[rows][cols]用到了它。
# 但是,该程序要求编译器支持变长数组这个特性