深入理解 C 指针阅读笔记 -- 第四章

Chapter4.h

#ifndef		__CHAPTER_4_
#define		__CHAPTER_4_

/*《深入理解C指针》学习笔记 -- 第四章*/

/*指针数组 -- 意思就是这是一个数组,这个数组中存储的是指针*/
void __pointers_array_test();

/*二维数组与指针的联系*/
void __two_dimension_array_test();

/*二维数组的连续内存和不连续的内存*/
void __two_dimension_memory_test();

/*不规则数组*/
//void __jagged_array_test();

#endif

Chapter.cpp

#include "Chapter4.h"
#include <stdio.h>
#include <malloc.h>

/*指针数组 -- 意思就是这是一个数组,这个数组中存储的是指针*/
void __pointers_array_test()
{
	int* test1[5];
	int i;

	for (i = 0; i != 5; ++i)
	{
		/*数组中的每一个元素都是指针,所以,用它们之前需要申请一定的内存*/
		test1[i] = (int*)malloc(sizeof(int));
		
		/*对指针进行解引用可以得到指针指向的值*/
		*(test1[i]) = i + 1;
	}

	for (i = 0; i != 5; ++i)
		printf("%d\t", *(*(test1 + i)));  /*获取指针指向的值的另一种方法,两次进行解引用*/
	/*
		第一次解引用得到的是某一个指针
		第二次解引用得到的是那个指针指向的值
	*/

	printf("\n");
}

void __two_dimension_array_test()
{
	int test1[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
	int i, j;

	for (i = 0; i != 2; ++i)
	{
		for (j = 0; j != 5; ++j)
		{
			printf("test1[%d][%d] address is : %x, value is : %d\n", i, j, &test1[i][j], test1[i][j]);
		}
	}

	printf("\n");

	printf("test1 address is : %x\n", test1);
	printf("test1 + 1 address is : %x\n", test1 + 1);

	/*
		程序的输出结果如下所示:
		test1[0][0] address is : 3df780, value is : 1
		test1[0][1] address is : 3df784, value is : 2
		test1[0][2] address is : 3df788, value is : 3
		test1[0][3] address is : 3df78c, value is : 4
		test1[0][4] address is : 3df790, value is : 5

		test1[1][0] address is : 3df794, value is : 6
		test1[1][1] address is : 3df798, value is : 7
		test1[1][2] address is : 3df79c, value is : 8
		test1[1][3] address is : 3df7a0, value is : 9
		test1[1][4] address is : 3df7a4, value is : 10

		test1 address is : 3df780
		test1 + 1 address is : 3df794

		可以看到,二维数组的名字输出的地址是第一个元素的起始地址,
		对数组名字做加1操作,得到的结果是 (原来的地址 + 列数 * 元素大小)
	*/
}

void __two_dimension_memory_test()
{
	/*这里的二维数组中的元素的内存地址一定是连续的*/
	int test1[2][2] = {{1, 2}, {3, 4}};
	int i, j;

	for (i = 0; i != 2; ++i)
	{
		for (j = 0; j != 2; ++j)
		{
			printf("test1[%d][%d] address is : %x\n", i, j, &test1[i][j]);
		}
	}

	/*
		输出结果如下:
		test1[0][0] address is : 32f9a0
		test1[0][1] address is : 32f9a4
		test1[1][0] address is : 32f9a8
		test1[1][1] address is : 32f9ac
	*/

	printf("\n");

	/*这里的动态二维数组的元素内存不一定是连续的,因为在其中调用了两次 malloc 函数*/
	int** test2 = (int**)malloc(sizeof (int*) * 2);
	for (i = 0; i != 2; ++i)
		test2[i] = (int*)malloc(sizeof(int) * 2);

	for (i = 0; i != 2; ++i)
	{
		for (j = 0; j != 2; ++j)
		{
			printf("test2[%d][%d] address is : %x\n", i, j, &test2[i][j]);
		}
	}

	/*
		输出结果如下:
		test2[0][0] address is : 67a8f8
		test2[0][1] address is : 67a8fc
		test2[1][0] address is : 67a930
		test2[1][1] address is : 67a934
	*/

	printf("\n");

	/*两种分配内存的方法使得动态二维数组分配的数组中的元素是连续的*/
	int rows = 2; 
	int cols = 2;

	/*第一种方法*/
	/*为每一行申请内存*/
	int** test3 = (int**)malloc(sizeof(int*) * rows);
	/*一次性的为所有的元素申请所需要的内存,所以,得到的内存是连续的*/
	test3[0] = (int*)malloc(sizeof(int) * rows * cols);

	for (i = 1; i != rows; ++i)
		test3[i] = test3[0] + i * cols;

	for (i = 0; i != rows; ++i)
	{
		for (j = 0; j != cols; ++j)
		{
			printf("test3[%d][%d] address is : %x\n", i, j, &test3[i][j]);
		}
	}

	/*
		输出结果如下:
		test3[0][0] address is : 5fa9a0
		test3[0][1] address is : 5fa9a4
		test3[1][0] address is : 5fa9a8
		test3[1][1] address is : 5fa9ac
	*/

	printf("\n");

	/*第二种方法*/
	/*用一维数组的形式,一次性的申请所有的内存*/
	/*
		这种方法的缺点是,我们不能再利用下标来引用数组中的元素,因为,这种方法丢失了
		编译器需要知道的二维数组形态
	*/
	int* test4 = (int*)malloc(sizeof(int) * rows * cols);

	for (i = 0; i != rows; ++i)
	{
		for (j = 0; j != cols; ++j)
		{
			printf("test4[%d][%d] address is : %x\n", i, j, test4 + (i * cols) + j);
		}
	}

	/*
		输出结果如下:
		test4[0][0] address is : 34a9e0
		test4[0][1] address is : 34a9e4
		test4[1][0] address is : 34a9e8
		test4[1][1] address is : 34a9ec
	*/
}

/*不规则数组*/
//void __jagged_array_test()
//{
	/*复合字面量创建二维数组*/
	/*int (*(test1[])) = 
	{
		(int[]) {0, 1, 2},
		(int[]) {3, 4, 5},
		(int[]) {6, 7, 8}
	};*/
//}


  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值