`
EGG_BMJIAOYANG
  • 浏览: 5216 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

C/C++中二维数组的分配

    博客分类:
  • C++
c++ 
阅读更多

在C/C++中动态分配二维数组可以先申请一维的指针数组,然后该数组中的每个指针再申请数组,这样就相当于二维数组了,但是这种方法会导致每行可能不相邻,从而访问效率比较低。如何申请连续的二维数组了?本文将分别三个方面讲解:
一.动态申请列大小固定的二维数组

二.C语言中动态申请连续的二维数组

三.C++语言中动态申请连续的二维数组


一.动态申请列大小固定的二维数组
首先如果二维数组的列大小固定,那么很简单,可以用申请一维数数组再其指针强制转化成为二维数组指针即可。详见代码: 

//列大小固定的二维数组可以申请一维数据并将指针强转成二维数组
#include <stdio.h>
int main()
{
	printf("  列大小固定的二维数组可以申请一维数据并将指针强转成二维数组\n");  
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");  

	//列值固定
	const int MAXCOL = 3;

	int nRow;
	printf("请输入二维数组的行数(列值固定为%d): ", MAXCOL);
	scanf("%d", &nRow);

	//申请一维数据并将其转成二维数组指针
	int *pp_arr = new int[nRow * MAXCOL];
	int (*p)[MAXCOL] = (int(*)[MAXCOL])pp_arr;

	//为二维数组赋值
	int i, j;
	for (i = 0; i < nRow; i++)
		for (j = 0; j < MAXCOL; j++)
			p[i][j] = i + j;
	
	//输出二维数组
	for (i = 0; i < nRow; i++)
	{
		for (j = 0; j < MAXCOL; j++)
			printf("%5d", p[i][j]);
		putchar('\n');
	}

	//释放资源
	delete[] pp_arr;
	return 0;
}

 

运行结果如下所示:

 

 

二.C语言中动态申请连续的二维数组

上面的方法虽然方便,但必须要求列的大小固定。下面先来试下在C语言中如何动态申请连续的二维数组。可以采用多申请一些指针,然后这一些指针分别指向后面数据区中对应的位置,如一个3*4int类型数组,我们先申请大小为sizeof(int*) * 3 + 3 * 4 * sizeof(int)的一维数组设为arr。然后arr[0]存放指向arr + sizeof(int*) * 3这个位置的指针,arr[1]存放指向arr + sizeof(int*) * 3 + 4 * sizeof(int)这个位置的指针, arr[2]存放指向arr + sizeof(int*) * 3 + 2 * 4 * sizeof(int)这个位置的指针。下面用图展示指向的示意:

 

详细代码如下,由于指针操作有点小复杂,请读者耐心看:

//C语言中动态的申请二维数组 malloc free
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//动态申请二维数组
template <typename T>
T** malloc_Array2D(int row, int col)
{
	int size = sizeof(T);
	int point_size = sizeof(T*);
	//先申请内存,其中point_size * row表示存放row个行指针
	T **arr = (T **) malloc(point_size * row + size * row * col);
	if (arr != NULL)
	{	
		memset(arr, 0, point_size * row + size * row * col);
		T *head = (T*)((int)arr + point_size * row);
		while (row--)
			arr[row] = (T*)((int)head + row * col * size);
	}
	return (T**)arr;
}
//释放二维数组
void free_Aarray2D(void **arr)
{
	if (arr != NULL)
		free(arr);
}
int main()
{
	printf("  C语言中动态的申请二维数组 malloc free\n");  
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

	printf("请输入行列(以空格分开): ");
	int nRow, nCol;
	scanf("%d %d", &nRow, &nCol);

	//动态申请连续的二维数组
	int **p = malloc_Array2D<int>(nRow, nCol);

	//为二维数组赋值	
	int i, j;	
	for (i = 0; i < nRow; i++)
		for (j = 0; j < nCol; j++)
			p[i][j] = i + j;

	//输出二维数组	
	for (i = 0; i < nRow; i++)
	{
		for (j = 0; j < nCol; j++)
			printf("%4d ", p[i][j]);
		putchar('\n');
	}

	free_Aarray2D((void**)p);
	return 0;
}

 

运行结果如下:

 

三.C++语言中动态申请连续的二维数组

可以看出我们已经成功实现了在C语言中动态申请连续的二维数组,如果上面的程序不使用int类型而使用string类这种类型,那会有什么后果了?肯定的说,由于没有调用构造函数和析构函数,程序绝对会造成内存泄露。因此要做下改进,下面给出在C++语言中动态申请连续的二维数组的代码,有些C++语法可能平时见得少,但其实这些语法在STL里面运用还是比较多的,有兴趣的童鞋应该掌握下。

//C++语言中动态的申请二维数组 new delete
#include <new>
#include <cstdio>
#include <cstdlib>
#include <string>
using namespace std;
//动态申请二维数组
template <typename T>
T** new_Array2D(int row, int col)
{
	int size = sizeof(T);
	int point_size = sizeof(T*);
	//先申请内存,其中sizeof(T*) * row表示存放row个行指针
	T **arr = (T **) malloc(point_size * row + size * row * col);
	if (arr != NULL)
	{	
		T *head = (T*)((int)arr + point_size * row);
		for (int i = 0; i < row; ++i)
		{
			arr[i] =  (T*)((int)head + i * col * size);
			for (int j = 0; j < col; ++j)
				new (&arr[i][j]) T;
		}
	}
	return (T**)arr;
}
//释放二维数组
template <typename T>
void delete_Array2D(T **arr, int row, int col)
{
	for (int i = 0; i < row; ++i)
		for (int j = 0; j < col; ++j)
			arr[i][j].~T();
	if (arr != NULL)
		free((void**)arr);
}
int main()
{
	printf("  C++语言中动态的申请二维数组 new delete\n");  
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

	printf("请输入行列(以空格分开): ");
	int nRow, nCol;
	scanf("%d %d", &nRow, &nCol);

	//动态申请连续的二维数组
	string **p = new_Array2D<string>(nRow, nCol);

	//为二维数组赋值
	int i, j;
	for (i = 0; i < nRow; i++)
		for (j = 0; j < nCol; j++)
		{
			char szTemp[30];
			sprintf(szTemp, "(第%d行,第%d列)", i, j);
			p[i][j] = szTemp;
		}

	//输出二维数组	
	for (i = 0; i < nRow; i++)
	{
		for (j = 0; j < nCol; j++)
			printf("%s ", p[i][j].c_str());
		putchar('\n');
	}

	delete_Array2D<string>(p, nRow, nCol);
	return 0;
}

 

运行结果如下:

 

分享到:
评论

相关推荐

    C/C++中二维指针的应用测试程序

    在C/C++编程中,二维指针是一种强大的工具,它被用来表示多维数组或矩阵。二维指针的使用涉及到动态内存分配、数组操作以及内存管理等核心概念。本篇文章将详细探讨这些知识点,并结合提供的链接(由于此处无法直接...

    java 二维数组

    虽然Java语言并没有提供真正意义上的多维数组(如C/C++中的那样),但通过嵌套使用一维数组的方式可以实现类似的功能。 #### 二、二维数组的基本语法 1. **声明二维数组**: - 声明一个二维数组的基本格式为:`...

    C/C++笔试题(全)word文档 流传笔试题汇总

    【C/C++笔试题解析】 在C/C++的笔试题中,常见的问题涵盖了语言的各个方面,包括基础语法、数据结构、算法以及特定概念的理解。以下是对一些常见知识点的详细解释: 1. **位操作**: - 题目1中的`func(x)`函数...

    C/C++ 笔试、面试题目大汇总

    从给定的文件信息中,我们可以总结出一系列关于C/C++编程语言的重要知识点,特别是针对笔试和面试场景下的常见问题。以下是对标题、描述、标签和部分内容中提及的知识点的详细解析: ### 1. 函数返回值计算 在微软...

    C/C++面试宝典(2009)

    在C/C++编程中,内存管理是至关重要的概念,尤其是对于面试来说,了解new、delete、malloc和free的关系以及它们的正确使用方式是基础。new和delete是C++中的运算符,负责对象的动态内存分配和释放,同时处理对象的...

    C/C++笔试面试题目大汇总

    ### C/C++笔试面试题目大汇总 #### 1. 求下面函数的返回值(微软) 函数示例代码如下: ```c++ int func(int x) { int count_x = 0; while (x) { count_x++; x = x & (x - 1); } return count_x; } ``` ...

    程序员必知:CC++面试题复习过程.pdf,这是一份不错的文件

    在C/C++编程中,面试题常常涉及到语言的核心概念,如指针、引用以及函数参数传递等。以下是对这些知识点的详细解释: 1. **位操作函数**:题目中的`func(x)`函数通过位操作计算整数x中二进制表示下的1的个数。这种...

    C&C++笔试题大全

    《C&C++笔试题大全》一书主要涵盖了C和C++编程语言的各类笔试题目,旨在帮助应聘者准备C++程序员和软件开发等职位的面试。以下是对书中的部分知识点的详细解释: 1. **位操作函数分析**: - `func` 函数通过位操作...

    CC++_笔试、面试题目大汇总.doc

    在IT行业的面试和笔试中,C++语言的相关知识是经常被考察的重点。以下是一些关于C++的关键知识点,包括函数、引用以及它们在面试和笔试中的应用。 1. **位操作函数**: - `func(x)` 函数通过位操作计算整数 `x` ...

    c、c++笔试题集锦

    从给定的文件信息中,我们可以提炼出一系列与C/C++相关的知识点,涵盖函数解析、引用的概念、引用作为函数参数的特性、常引用的应用场景以及引用作为函数返回值的格式与规则。以下是对这些知识点的详细说明: ### ...

    vc源代码合集.rar

    2012-06-11 08:52 190,100 C++中二维数组与指针关系的剖析.pdf 2012-06-11 08:48 171,862 C++函数后加const的意义.pdf 2012-06-11 08:57 9,174 C++注册表操作大全.txt 2012-06-11 08:37 113,664 CCheckListBox和...

    C C++ 笔试题集锦(找工作面试必读)

    《C C++ 笔试题集锦(找工作面试必读)》 C 和 C++ 是两种广泛应用的编程语言,尤其在系统编程和底层开发领域。掌握它们的基础知识和深入概念是找工作面试的重要准备。以下是一些关于 C/C++ 笔试题目和相关知识点的...

    C++笔试面试宝典2009版.doc

    `malloc`和`free`是C/C++标准库函数,而`new`和`delete`是C++特有的运算符。`new`不仅分配内存,还会调用构造函数初始化对象,而`delete`则负责调用析构函数清理资源。由于`malloc`和`free`不具备这样的功能,它们...

    最新c++笔试面试宝典

    1. **内存管理**:在C++中,`new`和`delete`是用于动态内存分配和释放的运算符,它们对应于C语言中的`malloc`和`free`。`new`会调用对象的构造函数,而`delete`会调用析构函数。`malloc`和`free`仅负责内存的分配和...

    C++面试大全

    - **malloc** 和 **free** 是C/C++标准库函数,用于动态内存的分配和释放。 - `malloc` 分配内存但不会调用构造函数。 - `free` 释放内存但不会调用析构函数。 对于非内置数据类型的对象,仅使用 `malloc` 和 `...

    C、C++笔试题集锦.doc

    《C、C++笔试题集锦》文档涵盖了多个C++编程中的关键概念,特别是关于“引用”的深入讨论。引用在C++中是一个重要的特性,它提供了另一种方式来处理变量,类似于指针,但又有所不同。 1. 题目1考察了位操作。`func...

    C C++面试笔试题精华

    C 和 C++ 面试笔试题中涵盖了各种核心概念,包括函数、引用、常引用以及函数参数和返回值的处理。以下是对这些知识点的详细解释: 1. **位操作函数**: 函数 `func(x)` 使用了位操作来计算整数 `x` 中二进制表示中...

    自己总结的面试常见题\C、C++\C、C++笔试题笔试题2

    - **数组引用**:不能声明数组的引用,因为数组本身就是一个固定大小的实体,不能通过引用改变其大小。 #### 3. 引用作为函数参数的特点 - **传递机制**:与指针相似,引用传递避免了复制参数的开销,提高了函数...

    C、C++笔试题集锦

    在C++编程语言中,笔试题集锦通常涵盖了一系列核心概念和技术,旨在测试候选人的编程能力。以下是针对题目中提及的一些关键知识点的详细解释: 1. **位操作**: - `func(x)` 函数通过位操作计算整数x中二进制表示...

    一些公司的C++笔试

    String类通常用于封装C风格的字符数组,提供更安全和方便的字符串操作。给出的实现包含了构造函数、拷贝构造函数、赋值运算符重载和析构函数。构造函数根据输入的字符串动态分配内存,并复制字符串内容。拷贝构造...

Global site tag (gtag.js) - Google Analytics