c语言中的指针和数组
来源:互联网 发布:手机安全软件排名 编辑:程序博客网 时间:2024/05/17 02:50
最近在复习c语言,看了C Primer Plus 这本书,对其中难以理解的数组和指针有一些自己小小的体会,现记录下来。
指针和一维数组:
其中使我更加深刻的理解了指针与数组配合的工作机制:
1,最基本的,一维数组名就是它的首地址,当以数组为实际参数传递给其他函数时,其他函数的形式参量实际就是指向数组元素的指针类型,而此时传递实际参数时,就可以直接传递数组名。
2,可以对指向数组元素的指针做增量运算,(可以使用自增运算符),因为指针本身是变量
3,当对指向数组的指针做加法运算时(加一个常数时),表示的是这个常数与指针所指的数据类型相乘后加到原始地址上
4,也可以做减法运算,可以减去一个整数,结论同上;也可以减去指向同一数组中较小的指针,注意不要越界,剩下的整数即为这个数组中两个指针指向元素之间的距离,注意并不一定是实际距离,这个距离指的是元素的个数。
指针和多维数组:
指针和多维数组这里主要讨论二维数组,相较于一维数组,二维数组麻烦多了,而且一不小心就被绕进去,当初也是花了很多时间才稍有理解。
由上面代码即输出结果可得
1, zippo 和 zippo[0] 和 *zippo 中所储存的地址值是一样的。 但我知道这不是一种巧合,因为zippo是二维数组名,实际上它保存的内容是含有两个int型元素的数组的地址,而zippo[0],
实际上,它保存的是一个int型数的地址,用符号表示即 zippo = &zippo[0], zippo[0] = &zippo[0][0], 所以zippo保存的是两个整数大小的对象的,而zippo[0]实际上 保存的是一个整数大小的对象的地址,但是由两个int型数和一个int型数组成的数组都开始于同一地址,所以zippo才会和zippo[0]中所保存的地址是同一个。
2, 由于zippo相当于指向了含有两个int型元素数组,所以当想要访问zippo[0][0],即整个二维数组的第一个元素时,需要用 **zippo。
原因如下:
zippo = &zippo[0], 所以*zippo = *&zippo[0] 即 *zippo = zippo[0],
然而实际上zippo[0]中存放的也是地址,只不是是一个int型数的地址,所以此时 *zzipo只能访问到一个int型数的地址。
所以由 zippo[0] = &zippo[0][0] 可得 *zippo[0] = zippo[0][0],而*zippo[0] = **zippo,
所以可得**zippo = zippo[0][0];
这样才访问到了二维数组中第一个元素的内容。
3, 由第一点,因为zippo是二维数组名,实际上它保存的内容是含有两个int型元素的数组的地址,而zippo[0],实际上,它保存的是一个int型数的地址,用符号表示即 zippo = &zippo[0], zippo[0] = &zippo[0][0], 所以zippo保存的是两个整数大小的对象的,而zippo[0]保存的是一个整数大小的对象的地址,所以才有了下面zippo + 1 的内容比 zippo 的内容大 Ox8。相应的(zippo[0] + 1)比zippo[0]大 Ox4;
总结:实际上,zippo的内容是&zippo[0],而zippo[0]的内容是&zippo[0][0],他们或许本来应该不一样的,zippo可以说是一个指向指针的指针,而zippo[0] 只是一个简单的指向一个int元素的指针,但是关键的地方是,zippo中存放的内容和zippo[0]中存放的内容相等,也就是说他们实际上指向的是同一块区域,这是为什么? 是因为二维数组的开始就是第一行第一列的那个元素,也就是zippo[0][0]的地址,无论多少重指针指向它,所得的内容还是这个元素的地址,(即使是zippo[0][0][0],zippo[0][0][0][0]还是同一个元素),所以实际上zippo[0]在某种程度上来说就是zippo[0][0],但因为它是第一行的数组的数组名,所以它里面的元素是&zippo[0][0]而已。
指针和一维数组:
#include <stdio.h> int urn[5] = {100, 200, 300, 400, 500}; int main(void) { int *ptr1, *ptr2, *ptr3; ptr1 = urn; // 把数组的第一个元素的地址赋给指针 ptr2 = &urn[2]; // 把数组的第三个元素的地址赋给指针 printf("pointer value, dereferenced pointer, pointer address:\n"); printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); ptr3 = ptr1 + 4; // 把ptr1所指内存的地址加上ptr1保存的类型的字节数*4之和赋给ptr3 即把&urn[4]赋给ptr3 printf("\nadding an int to a pointer:\n"); printf("ptr1 + 4 = %p, *(ptr1 + 3) = %d\n", ptr1 + 4, *(ptr1 + 3)); ptr1++; // 对ptr1使用自增运算符,注意自增运算符只能当ptr1被声明为变量时才能使用,若ptr1为一个数组名称则不能这样用,因为数组的首地址是一个常量。 printf("\nvalue after ptr1++:\n"); printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); ptr2--; // 同理 printf("\nvalue after ptr2--:\n"); printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2); //此时ptr1 和ptr2 都指向同一个内存地址 --ptr1; // 把ptr1和ptr2的值恢复 ++ptr2; printf("\npointers reset to original values.\n"); printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2); printf("subtracting one pointer from another.\n"); printf("ptr1 = %p, ptr2 = %p\n, ptr2 - ptr1 = %d\n", ptr1, ptr2, ptr2 - ptr1); printf("subtracting an int from a pointer.\n"); printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2); // 同理此时ptr3 - 2表示ptr3所指的地址减掉2 * 它所指向的字节数 } // 输出结果如下: /* pointer value, dereferenced pointer, pointer address: ptr1 = 00407000, *ptr1 = 100, &ptr1 = 0061ff08 adding an int to a pointer: ptr1 + 4 = 00407010, *(ptr1 + 3) = 400 value after ptr1++: ptr1 = 00407004, *ptr1 = 200, &ptr1 = 0061ff08 value after ptr2--: ptr2 = 00407004, *ptr2 = 200, &ptr2 = 0061ff04 pointers reset to original values. ptr1 = 00407000, ptr2 = 00407008 subtracting one pointer from another. ptr1 = 00407000, ptr2 = 00407008 , ptr2 - ptr1 = 2 subtracting an int from a pointer. ptr3 = 00407010, ptr3 - 2 = 00407008 */
其中使我更加深刻的理解了指针与数组配合的工作机制:
1,最基本的,一维数组名就是它的首地址,当以数组为实际参数传递给其他函数时,其他函数的形式参量实际就是指向数组元素的指针类型,而此时传递实际参数时,就可以直接传递数组名。
2,可以对指向数组元素的指针做增量运算,(可以使用自增运算符),因为指针本身是变量
3,当对指向数组的指针做加法运算时(加一个常数时),表示的是这个常数与指针所指的数据类型相乘后加到原始地址上
4,也可以做减法运算,可以减去一个整数,结论同上;也可以减去指向同一数组中较小的指针,注意不要越界,剩下的整数即为这个数组中两个指针指向元素之间的距离,注意并不一定是实际距离,这个距离指的是元素的个数。
指针和多维数组:
#include <stdio.h> int main(void) { int zippo[4][2] = {{2,4}, {6,8}, {1,3}, {5,7}}; printf(" zippo = %p, zippo + 1 = %p.\n", zippo, zippo + 1); // 打印二维数组名的内容(即其所指向的地址) printf(" zippo[0] = %p, zippo[0] + 1 = %p.\n", zippo[0], zippo[0] + 1); printf(" *zippo = %p, *zppo + 1 = %p.\n", *zippo, *zippo + 1); printf(" zippo[0][0] = %d\n", zippo[0][0]); printf(" *zippo[0] = %d\n", *zippo[0]); printf(" **zippo = %d\n", **zippo); printf(" zippo[2][1] = %d.\n", zippo[2][1]); printf("*(*(zippo + 2) + 1) = %d.\n", *(*(zippo + 2) + 1)); } /* zippo = 0061fef0, zippo + 1 = 0061fef8. zippo[0] = 0061fef0, zippo[0] + 1 = 0061fef4. *zippo = 0061fef0, *zppo + 1 = 0061fef4. zippo[0][0] = 2 *zippo[0] = 2 **zippo = 2 zippo[2][1] = 3. *(*(zippo + 2) + 1) = 3. */
指针和多维数组这里主要讨论二维数组,相较于一维数组,二维数组麻烦多了,而且一不小心就被绕进去,当初也是花了很多时间才稍有理解。
由上面代码即输出结果可得
1, zippo 和 zippo[0] 和 *zippo 中所储存的地址值是一样的。 但我知道这不是一种巧合,因为zippo是二维数组名,实际上它保存的内容是含有两个int型元素的数组的地址,而zippo[0],
实际上,它保存的是一个int型数的地址,用符号表示即 zippo = &zippo[0], zippo[0] = &zippo[0][0], 所以zippo保存的是两个整数大小的对象的,而zippo[0]实际上 保存的是一个整数大小的对象的地址,但是由两个int型数和一个int型数组成的数组都开始于同一地址,所以zippo才会和zippo[0]中所保存的地址是同一个。
2, 由于zippo相当于指向了含有两个int型元素数组,所以当想要访问zippo[0][0],即整个二维数组的第一个元素时,需要用 **zippo。
原因如下:
zippo = &zippo[0], 所以*zippo = *&zippo[0] 即 *zippo = zippo[0],
然而实际上zippo[0]中存放的也是地址,只不是是一个int型数的地址,所以此时 *zzipo只能访问到一个int型数的地址。
所以由 zippo[0] = &zippo[0][0] 可得 *zippo[0] = zippo[0][0],而*zippo[0] = **zippo,
所以可得**zippo = zippo[0][0];
这样才访问到了二维数组中第一个元素的内容。
3, 由第一点,因为zippo是二维数组名,实际上它保存的内容是含有两个int型元素的数组的地址,而zippo[0],实际上,它保存的是一个int型数的地址,用符号表示即 zippo = &zippo[0], zippo[0] = &zippo[0][0], 所以zippo保存的是两个整数大小的对象的,而zippo[0]保存的是一个整数大小的对象的地址,所以才有了下面zippo + 1 的内容比 zippo 的内容大 Ox8。相应的(zippo[0] + 1)比zippo[0]大 Ox4;
总结:实际上,zippo的内容是&zippo[0],而zippo[0]的内容是&zippo[0][0],他们或许本来应该不一样的,zippo可以说是一个指向指针的指针,而zippo[0] 只是一个简单的指向一个int元素的指针,但是关键的地方是,zippo中存放的内容和zippo[0]中存放的内容相等,也就是说他们实际上指向的是同一块区域,这是为什么? 是因为二维数组的开始就是第一行第一列的那个元素,也就是zippo[0][0]的地址,无论多少重指针指向它,所得的内容还是这个元素的地址,(即使是zippo[0][0][0],zippo[0][0][0][0]还是同一个元素),所以实际上zippo[0]在某种程度上来说就是zippo[0][0],但因为它是第一行的数组的数组名,所以它里面的元素是&zippo[0][0]而已。
0 0
- c语言中的数组和指针
- c语言中的数组和指针
- c语言中的指针和数组
- 再论C语言中的指针和数组
- 小议C语言中的数组和指针
- C语言中的指针和数组
- C语言中的指针数组和数组指针
- C语言中的指针数组和数组指针
- C语言中的指针数组和数组指针
- C 语言中的数组类型和数组指针类型.
- C语言中的数组指针
- C语言中的指针数组
- c语言中的指针数组
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- 极客班 c++(下)第二周学习笔记 ——重载 operator new & operator delete
- Unfortunately,Launcher has stopped
- 应用时间序列分析(王燕)学习笔记3
- linux 下文件及目录函数
- androidstudio快捷键
- c语言中的指针和数组
- 欢迎使用CSDN-markdown编辑器
- Git for Ubuntu 14.01
- POJ-----1971Parallelogram Counting数学题
- CodeForces 686B Little Robber Girl's Zoo(模拟冒泡排序)
- emmc 分区管理
- linux cpu 内存 硬盘 系统性能调试相关命令
- 两个时间相减
- HDU 5306 Gorgeous Sequence(线段树)