使用二行三创建一个3行4列的二维数组组保存数据?

numpy get startednumpy 提供了一种数组类型,高维数组, 提供了数据分析的运算基础(业务表一般就是二维)import numpy as np导入numpy库,并查看numpy版本np.version一、创建Array1. 使用np.array()由python list创建C 数组的概念 : 数据类型一致的一个连续的内存空间python list列表 (C语言说:列表其实就是一个指针数组),列表不要求数据类型一致numpy的数组:同样是一个【有序】的,【相同数据类型】的集合[1, 3.14, ‘helloworld’, student]参数为列表:[1, 4, 2, 5, 3]numpy设计初衷是用于运算的,所以对数据类型进行统一优化注意:numpy默认ndarray的所有元素的类型是相同的如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int[1,3.14, ‘hello’]numpy的数组array = np.array([1])arrayarrayarraynd.arraynp.arrayimport numpy as npnames = [“tom”,“lucy”,“jack”]array1 = np.array(names)array1scores = [1.2, 3.4, 5.6]array2 = np.array(scores)array2age = [15,16,18]array3 = np.array(age, dtype=np.float32)array3money = [[1,2,3],[4,5,6]]np.array(money)2. 使用np的routines函数创建包含以下常见创建方法:np.ones(shape, dtype=None, order=‘C’)shape = (m,n) m行n列 二维数组shape = (m) m个元素的一维数组 [1,2,3]shape = (m,) m个元素的一维数组shape = (m, 1) m行1列 二维数组 [[1],[2],[3]]shape = (1, n) 1行m列 二维数组 [[1,2,3]]构造一个5行3列的二维数组np.ones(shape=(5,3), dtype=np.int8)构造长度为3的一维数组np.ones(shape=(3,))np.ones(shape=(3))构造一个5行1列的二维数组np.ones(shape=(5,1))构造1行3列的二维数组np.ones(shape=(1,3))np.zeros(shape, dtype=float, order=‘C’)np.zeros(shape=(5,6))np.zeros(shape=(5))np.zeros(shape=(5,3))np.zeros(shape=(2,3,4))np.full(shape, fill_value, dtype=None, order=‘C’)np.full(shape=(2,3), fill_value=6)np.eye(N, M=None, k=0, dtype=float)对角线为1其他的位置为0单位矩阵 l2正则项生成一个3阶单位矩阵(矩阵除法)np.eye(N=3)np.eye(N=5, M=4)np.eye(N=5, k=-1)np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)等差数列np.linspace(0,10,10, endpoint=False)np.arange([start, ]stop, [step, ]dtype=None)np.arange(0,10,step=1)np.random.randint(low, high=None, size=None, dtype=‘l’)size 同 shapenp.random.randint(0,100,size=(5,5))正态分布函数np.random.randn(d0, d1, …, dn) 标准正态分布np.random.normal() 普通正态分布np.random.randn(3,5)np.random.normal(loc=170, scale=5, size=(5,3))np.random.random(size=None)生成0到1的随机数,左闭右开np.random.random(size=(5,5))生成一组随机索引np.random.permutation(10)二、ndarray的属性4个必记参数:ndim:维度shape:形状(各维度的长度)size:总长度dtype:元素类型arr = np.random.randint(0,100,size=(5,4,3))arr.ndimarr.shapearr.size获取数组元素类型arr.dtype获取数组类型type(arr)创建属性如何访问如何计算三、ndarray的基本操作data = [[1,2,3],[4,5,6]]data[0]data[0][0]1. 索引一维与列表完全一致多维时同理arr1 = np.array([1,2,3,4,5])arr1[0]arr2 = np.array([[1,2,3],[4,5,6]])arr2列表的访问方式arr2[0][0]numpy特有的arr[m,n…] 描述的是对应维度的索引值arr2[0,0]arr2[1,2]高级用法arr11. 使用列表作为索引访问arr1[[0,1,2,0,1,2]]2. 使用BOOL列表作为索引访问, True对应的值会被返回bool_list = [True, False, True, False, True]arr1[bool_list]eg.获取数组中大于5的数arr1[arr1 > 3]arr3 = np.random.randint(0,10,size=(5,4,3))arr3arr3[2,0]arr3[0,1,2]赋值和访问没有区别,都可以使用2. 切片一维与列表完全一致多维时同理所有的切片方式都是开区间(左闭右开)arr1[0:3]arr2 = np.random.randint(0,100,size=(5,6))arr2行切片arr2[0:2]列切片 不论多少维,每一个维度的切片范围都是用冒号表示,使用逗号分割,最后一个维度可以省略,但是被切片的维度之前的维度不能省arr2[:,0:2]arr3 = np.random.randint(0,10,size=(3,4,5))arr3切前两个数组arr3[0:2]切割每一个二维数组的前两列arr3[:,:,0:2]切割每一个二维数组的前两行arr3[:,0:2]将数据反转,例如[1,2,3]---->[3,2,1]arr1[::-1]arr2arr2[::-1]arr2[:,::-1]两个::进行切片3. 变形使用reshape函数,注意参数是一个tuple!arr = np.random.randint(0,10,size=(20))arrarr.reshape((4,5))arr.reshape(3,7)4. 级联np.concatenate()级联需要注意的点:级联的参数是列表:一定要加中括号或小括号维度必须相同形状相符【重点】级联的方向默认是shape这个tuple的第一个值所代表的维度方向可通过axis参数改变级联的方向arr1 = np.random.randint(0,10,size=(3,3))arr2 = np.random.randint(10,20,size=(3,3))display(arr1, arr2)使用axis控制连接方向,axis指的是连接的维度axis 注意轴 非常常见np.concatenate((arr1, arr2), axis=1)np.hstack与np.vstack水平级联与垂直级联,处理自己,进行维度的变更horizontalnp.hstack((arr1, arr2))verticalnp.vstack((arr1, arr2))【注意】:级联的时候如果是横向级联,参与级联的数组的行数要一致纵向级联,参与级联的数组的列数要一致如果是高维数组的级联,级联的维度的数据个数要一致5. 切分与级联类似,三个函数完成切分工作:np.splitnp.vsplitnp.hsplitarr = np.random.randint(0,100,size=(6,6))arr直接指定切分的份数part1, part2 = np.split(arr, indices_or_sections=2)display(part1, part2)使用axis控制切分方向part1, part2, part3 = np.split(arr, indices_or_sections=3, axis=1)display(part1, part2, part3)arr2 = np.random.randint(0,100,size=(3,7))arr2indices_or_sections=[m,n] 表示的范围是0:m, m:n, n:part1, part2, part3 = np.split(arr2, indices_or_sections=[2,5], axis=1)display(part1, part2, part3)np.hsplit(arr2, indices_or_sections=[2,5])6. 副本所有赋值运算不会为ndarray的任何元素创建副本。对赋值后的对象的操作也对原来的对象生效。可使用copy()函数创建副本copy_array = arr.copy()arrcopy_array[0,0] = 1000arrcopy_array四、ndarray的聚合操作arr1. 求和np.sumarr = np.random.randint(0,10,size=10)arrarr.sum()求平均值arr.mean()arr.max()arr.min()求最大值索引arr.argmax()arrarr.argmin()标准方差arr.std()求方差arr.var()arr注意这个语法格式np.median(arr)arr.median()data = np.arange(0,11,step=1)data第一个参数是要求百分位数的数据第二个参数是要求的百分位的位置异常值检测会使用Q1 Q3np.percentile(data, [0.25, 0.75])平均值 (d1 + d2 + d3 + … dn)/n中位数方差 (d1-mean)**2 + (d2-mean)**2 + … + (dn-mean)**2/n标注差 sqrt(方差)any 检测一个BOOL数组中,是否至少存在一个Trueall 检测一个BOOL数组中,是否全为Truebool_list = np.array([False, True, False, False])bool_list.any()bool_list = np.array([True, True, True, True])bool_list.all()a = 10a > 10找出一组数据中,所有大于该组数据平均值的值arr广播运算, 支持一个numpy.arry和任意一个数运算condition = arr > arr.mean()conditionarr[condition]查看一个数组中,是否存在至少一个大于10的数(arr > 10).any()2. 最大最小值:np.max/ np.min同理any() 有True返回Trueall() 有False返回False3. 其他聚合操作Function Name NaN-safe Version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.argmin np.nanargmin Find index of minimum value
np.argmax np.nanargmax Find index of maximum value
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true
np.power 幂运算
np.sum 和 np.nansum 的区别nan not a number五、ndarray的矩阵操作1. 基本矩阵操作算术运算符:加减乘除矩阵积np.dot()a = np.array([[1,2],[3,4]])b = np.array([[1,1],[2,2]])display(a, b)使用符号是对应位置相乘a * b如果希望做数学中的矩阵运算np.dot(a, b)2. 广播机制arr3 3 3 3 3 3 3 3 3 3 3arr = np.array([1,2,3,4,5])data = 3arr + data【重要】ndarray广播机制的两条规则规则一:为缺失的维度补1规则二:假定缺失元素用已有值填充例1:m = np.ones((2, 3))a = np.arange(3)求M+am = np.ones((2,3))a = np.arange(3)display(m, a)m + am + 3不能广播运算的例子m = np.ones(shape=(3,3))n = np.array([[1,2],[3,4]])display(m, n)m + n例2:a = np.arange(3).reshape((3, 1))b = np.arange(3)求a+ba = np.arange(0,3,step=1).reshape((3, 1))b = np.arange(3)display(a, b)a + b习题a = np.ones((4, 1))b = np.arange(4)求a+b六、ndarray的排序小测验:使用以上所学numpy的知识,对一个ndarray对象进行冒泡排序。def bubleSort(x):代码越短越好1. 快速排序np.sort()与ndarray.sort()都可以,但有区别:np.sort()不改变输入ndarray.sort()本地处理,不占用空间,但改变输入data = np.random.permutation(10)datadata.sort()datanp.sort(data)2. 部分排序np.partition(a,k)有的时候我们不是对全部数据感兴趣,我们可能只对最小或最大的一部分感兴趣。当k为正时,我们想要得到最小的k个数当k为负时,我们想要得到最大的k个数data = np.random.permutation(10000)datanp.partition(data, 4)[:4]np.partition(data,-4)[-4:]在这里插入代码片}

以下数组定义中错误的是()A.intx[2][3]={1,2,3,4,5,6};B.intx[][3]={0};C.intx[][3]={{1,2,3},{4,5,6}}...
以下数组定义中错误的是()A. int x[2][3]={1,2,3,4,5,6};B. int x[][3]={0};C. int x[][3]={{1,2,3},{4,5,6}};D. int x[2][3]={{1,2},{3,4},{5,6}};选D,但是不明白ABC对在哪里
展开选择擅长的领域继续答题?
{@each tagList as item}
${item.tagName}
{@/each}
手机回答更方便,互动更有趣,下载APP
提交成功是否继续回答问题?
手机回答更方便,互动更有趣,下载APP
展开全部1. int x[2][3]={{1,2},{3,4},{5,6}}(1)这句的左边含义是:有一个二维数组,2行3列,一共就是6个int类型的数据。(2)这句的右边含义是:最里面的三个花括号,代表的是三行,每个花括号里有两个数据,代表的是每行有2列,所以代表的意思是:3行2列的一个int类型的二维数组。(3)2行3列和3行2列的两个二维数组,当然是不一样的。所以把后者赋值给前者。2. int x[][3]={0}:代表的是行数未知,列数是3的二维数组,把该数组里的数组全部赋值为0。(1)int x[][3]={{1,2,3},{4,5,6}}:这个等号右边是2行3列的int类型的数据(2)等号左边的x[][3]代表的是:行数未知,列数是3的二维数组,由于赋值操作,于是可以得出行数是2。(3)所以x[][3]是一个2行3列的一个二维数组,即:x[2][3]。已赞过已踩过你对这个回答的评价是?评论
收起
收起
更多回答(1)
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
为你推荐:
下载百度知道APP,抢鲜体验使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。扫描二维码下载
×个人、企业类侵权投诉
违法有害信息,请在下方选择后提交
类别色情低俗
涉嫌违法犯罪
时政信息不实
垃圾广告
低质灌水
我们会通过消息、邮箱等方式尽快将举报结果通知您。说明
做任务开宝箱累计完成0
个任务
10任务
50任务
100任务
200任务
任务列表加载中...
}
导读:本文概述数组,然后描述 数组表示法 和 指针表示法 的异同。我们可以使用malloc类函数创建动态数组,这类函数提供了比传统数组声明更大的灵活性。我们也要了解如何用realloc函数调整数组的内存。我们也要 了解在传递和返回数组时可能产生的问题 ,通常需要给函数传递数组长度以便函数能正确处理数组。我们还研究了如何在C中创建不规则数组。一、数组概述数组是C语言的内建的数据组织形式。数组为我们提供了连续存储数据或数据特征的一种手段。我们可以使用数组内部的索引方式来方便操作数据。不同类型的数组形成不同的数组类型。//连续的字符数组,来容纳字符串
char stringArray[30];
//连续的整数数组,容纳轻型数据
int array[30];
//连续的函数指针数组,用数组保存函数地址,以便调用
typedef void (*functionPtr)(int, char /*其他参数*/)
functionPtr array[30] = {NULL};
//容纳复杂数据的数组(数据复杂,数据存储开销大的时候,我们一般用数组存储数据的地址)
typedef struct
{
char infoOne;
char infoTwo;
char infoThree;
//其他数据
//........
} OtherInfo;
typedef struct
{
int ID;
char *UserName;
char Sex;
long PhoneNumber;
char *Address;
char *Email;
OtherInfo Info;
} Item;
Item* itemArray[100];
1、一维数组一维数组是线性结构,用一个索引访问成员。下面的代码声明了一个5个元素的整数数组:int vector[5];
printf("%d\n",sizeof(vector)/sizeof(int));
数组索引从0开始,到声明的长度减1结束。vector数组的索引从0开始,到4结束。C并没有强制规定边界,要靠我们自己确定边界。用无效的索引访问数组会造成不可预期的行为。2、二维数组二维数组使用行和列来标识数组元素,这类数组需要映射为内存中的一维地址空间。在C中这是通过行-列顺序实现的。先将数组的第一行放进内存,接着是第二行、第三行,直到最后一行。所以我们有时候看到这样的写法是对的://可以忽略行数,但是不可以忽略列数;因为列数是限制行数的。
int array[][6]
看下图声明和内存示意图int matrix[2][3]={{1,2,3},{4,5,6}};
3、多维数组多维数组具有两个及两个以上维度。对于多维数组,需要多组括号来定义数组的类型和长度。下面的例子中,我们定义了一个具有3行、2列、4阶的三维数组。阶通常用来标识第三维元素。//可以忽略第一维,但是不能忽略维度
//int arr3d[][2][4]={};
int arr3d[3][2][4]=
{
{{1,2,3,4},{5,6,7,8}},
{{9,10,11,12},{13,14,15,16}},
{{17,18,19,20},{21,22,23,24}}
};
元素按照行-列-阶的顺序连续分配二、指针表示法和数组要学懂指针和数组;本质上还是要搞清楚他们原来最朴素的原理指针:是一个变量;存放的值很特殊:其他变量的地址;由地址可以改变变量的数据数组:数组名就是数组首地址(数组被设计的时候就为了节约内存开销,使用的是传递数组名【也就是传递数组首地址】)int vector[5]={1,2,3,4,5}
int *pv=vector;
pv 是指向整数的指针变量,也是指向数组第一个元素而不是指向数组本身的指针。指向整数数组的指针和指向整数的指针不一样哦【指向数组本身的地址写法:&vector】给 pv赋值是把数组的第一个元素的地址赋给 pv。又因为数组是连续的,如果指针能够偏移就可以访问数组其他元素的内存了。刚好 指针的运算:加法,减法,比较 就能实现 指针 移动指针类型长度的地址下面这些写法都是输出数组首元素地址printf("%p\n",vector);
printf("%p\n",&vector[0]);
我们可以运用数组的索引括号int i;
(pv + i) == pv[i];
pv[i] == vector[i];
假设vector位于地址100,pv位于地址96,表4-1和图4-4说明了如何利用数组下标和指针算术运算分别从数组名字和指针得到不同的值。地址值表达式数组名偏移等价指针描述数组元素地址等价指针描述地址等价92&vector[-2]vector - 2&pv[-2]pv - 2100vectorvector + 0&pv[0]pv100&vector[0]vector + 0&pv[0]pv104&vector[1]vector + 1&pv[1]pv + 1140&vector[10]vector + 10&pv[10]pv + 10其内存是示意图:三、用malloc创建一维数组创建很简单;我一般使用堆区数组的时候、我一般使用 方式二,这提醒我用的是地址索引。int*pv=(int*)malloc(5*sizeof(int));
//数组访问方式一
for(int i=0;i < 5;i++)
{
pv[i]=i+1;
}
//数组访问方式二
for(int i=0; i < 5; i++)
{
*(pv+i)=i+1;
}
//记得手动释放 free(pv); 并释放pv的引用:pv = NULL;
说明了本例的内存分配。四、用realloc调整数组长度realloc函数主要就是在现有的基础上(基础可以是0字节内存也是传ptr为NULL)扩容,可以实现动态扩容//函数声明:
void *realloc( void *ptr, size_t new_size );
// 参数说明:
// ptr - 指向需要重新分配的内存区域的指针 (也就是就内存区的首地址)
// new_size - 数组的新大小(字节数)
// 返回值
//成功时,返回指向新分配内存的指针。返回的指针必须用 free() 或 realloc() 归还。
//失败时,返回空指针。原指针 ptr 保持有效,并需要通过 free() 或 realloc() 归还。
注意要点:重新分配给定的内存区域。它必须是之前为 malloc() 、 calloc() 或 realloc() 所分配,并且仍未被 free 或 realloc 的调用所释放,否则会出错。若无足够内存,则不释放旧内存块,并返回空指针。若 ptr 为 NULL ,则行为与调用 malloc(new_size) 相同。如果realloc分配成功,我们不需要释放旧的buffer,因为realloc会把原来的缓冲区复制到新的缓冲区中,再把旧的释放。 如果试图释放buffer,十有八九程序会终止,因为我们试图重复释放同一块内存。重新分配按以下二者之一执行:五、传递一维数组因为数组是确定数量的数据块,不管是数组表示法还是指针表示法都是得传递数组的个数,当然我们也可以学习字符串的那种方法,约定数组结尾是特殊值也能不需要传数组长度1、用数组表示法直接传入的数组名,本质上还是数组首地址//传入数组名、可以指针数组长度, arr[5]也可以不用:arr[]
void displayArray (int arr [] , int size)
{
for(inti=0;i<size;i++)
{
printf("%d\n", arr[i]);
}
}
int vector[5]={1,2,3,4,5};
displayArray(vector,5);
2、用指针表示法声明函数的数组参数不一定要用方括号表示法,也可以用指针表示法,如下所示:void displayArray(int*arr,int size)
{
for (int i = 0; i < size; i++)
{
printf("%d\n",arr[i]);
}
}
在函数内部我们仍然使用数组表示法,如果有需要,也可以用指针表示法:void displayArray(int*arr,int size)
{
for(inti=0;i<size;i++)
{
printf("%d\n",*(arr+i));
}
}
如果在声明函数时用了数组表示法,在函数体内还是可以用指针表示法:void displayArray(int arr[], int size)
{
for(inti=0;i<size;i++)
{
printf("%d\n",*(arr+i));
}
}
总结1、数组和指针本质上是有区别的2、数组和指针都可以通过地址访问;两种可以互相访问3、数组的 [ ] 符号可以看成相对于首地址位置偏移的元素接引
arr[1] = *(arr + 1)六、一维指针数组整数数组 :数组元素是一个个整数的集合int array[5] = {0, 1, 2, 3, 4};
指针数组:数组元素是一个个指针的集合int array[5] = {0, 1, 2, 3, 4};
int *ptrVector[5] =
{array, array+1, array+2, array+3, array+4};
完整实例:#include <stdio.h>
int main()
{
int array[5] = {0, 1, 2, 3, 4};
int *ptrVector[5] = {array, array+1, array+2, array+3, array+4};
//遍历整数数组
printf("遍历整数数组: \n");
for(int i=0; i < 5; i++ )
{
printf("%d ", *(array+i));
}
//遍历指针数组
printf("\n遍历指针数组:\n");
for(int i=0; i < 5; i++ )
{
printf("%d ", *(*ptrVector+i));
}
return 0;
}
//运行结果:
遍历整数数组:
0 1 2 3 4
遍历指针数组:
0 1 2 3 4
部分变量表变量名地址值内容值ptrVector0x2000x100*ptrVector-0x100(*ptrVector)
-
0内存示意图:注意这里可以使用 第五条的表示方法*(ptrVector[i])
== 0
ptrVector[0][0] == 0
完整实例:#include <stdio.h>
int main()
{
int array[5] = {0, 1, 2, 3, 4};
int *ptrVector[5] =
{array, array+1, array+2, array+3, array+4};
//遍历整数数组
printf("遍历整数数组: \n");
for(int i=0; i < 5; i++ )
{
printf("%d ", *(array+i));
}
//遍历指针数组
printf("\n遍历指针数组:\n");
for(int i=0; i < 5; i++ )
{
// printf("%d ", *(*ptrVector + i));
// printf("%d ", *(ptrVector[i]));
printf("%d ", ptrVector[i][0]);
//这第二个索引一维数组时必须是0
}
return 0;
}
//输出结果:
遍历整数数组:
0 1 2 3 4
遍历指针数组:
0 1 2 3 4
七、指针和多维数组1、数组是按行-列顺序存储,也就是说,将第一行按顺序存入内存,后面紧接着第二行。多维数组也是如此扩展的:如三维数组按照 行-列-秩 扩展。行可以忽略(也即是第一维可忽略值):int array[] = {1,2,3};
int array_two[][2] = {{1,2}, {12,321}};
int array_three[][2][3] = { };
2、可以将多维数组的一部分看做子数组。 比如说,二维数组的每一行都可以当做一维数组。我们使用这样的一层层的解释数组,就可以把高维数组看成比它低一维的数组的一维数组。我们就可以理解这种写法:array[0] : 二维数组中第一个节点数组array[0][1]: 二维数组中第一个节点数组的第二个子元素int array[3][2]= {{1, 2}, {3, 4}, {5, 6}};
int number = array[0][1];
//这里的 number == 2
我们可以声明一个指针处理二维数组,如下所示:int matrix[2][5] = {{1,2,3,4,5},{6,7,8,9,10}};
//这是数组指针
int(*pmatrix)[2]=matrix;
//这是指针数组
int * ptrmatrix[2]={matrix, matrix + sizeof(int) * 5};
*(pmatrix)表达式声明了一个数组指针,上面的整条声明语句将pmatrix定义为一个指向二维数组的指针,该二维数组的元素类型是整数,每列有2个元素。如果我们把括号去掉就声明了2个元素的数组,数组元素的类型是整数指针。如果要用指针表示法访问第二个元素(就是2),下面的代码看似合理://指针数组
printf("addr: %p , value: %d\n", matrix, **matrix);
printf("addr: %p , value: %d\n", matrix+1, *(*matrix+1));
//数组指针
printf("addr: %p , value: %d\n", ptrmatrix, **ptrmatrix);
printf("addr: %p , value: %d\n", ptrmatrix+1, *(*ptrmatrix+1));
完整代码#include <stdio.h>
int main()
{
int matrix[2][5] = {{1,2,3,4,5},{6,7,8,9,10}};
//这是数组指针
int(*pmatrix)[2]=matrix;
//这是指针数组
int * ptrmatrix[2]={matrix, matrix + sizeof(int) * 4};
//指针数组
printf("addr: %p , value: %d\n", pmatrix, **pmatrix);
printf("addr: %p , value: %d\n", pmatrix+1, *(*pmatrix+1));
//数组指针
printf("addr: %p , value: %d\n", ptrmatrix, **ptrmatrix);
printf("addr: %p , value: %d\n", ptrmatrix+1, *(*ptrmatrix+1));
return 0;
}
//程序输出
addr: 0x7ffc261735f0 , value: 1
addr: 0x7ffc26173604 , value: 2
addr: 0x7ffc261735e0 , value: 1
addr: 0x7ffc261735e8 , value: 2
这里的 matrix+1 与 matrix的地址差是 0x7ffc26173604 - 0x7ffc261735f0 == 20也就是一个一行元素的 5 x 4 字节;是每一行的地址,跨度是列的字节总数printf(“%d\n”,sizeof(matrix[0])); // 显示20第二种用的数组指针,我们是手动定位到数组的首行以及第二行的首地址,这里的数组地址和第一个元素的地址有区别的。这是指针和数组的内存指向图同样的,这里可以使用数组的 [ ] 索引符*matrix[0] == 1*(matrix[0] + 1) == 2*(*matrix+1))== 2数组索引计算如下:arr[i][j] == address of arr + [ (i * size of row) + (j " size of element) ]数组元素地址 == 数组首地址+相对偏移量八、传递多维数组要想在函数内部使用数组表示法,必须指定数组的形态,否则,编译器就无法使用下标。//要传递数组matrix,可以这么写:
void display2DArray(int arr[][5], int rows);
//或者这么写:
void display2DArray(int(*arr)[5],int rows);
这两种写法都指明了数组的列数,这很有必要,因为编译器需要知道每行有几个元素。如果没有传递这个信息,编译器就无法计算上面的数组索引计算{ arr[i][j] == address of arr + [ (i * size of row) + (j " size of element) ] }这样的表达式。
注意: 数组的下标 [ ] 符号在这种情况下是无法使用的:void display2DArray(int*arr[2], int rows)因为这是传递整数地址 而不是数组地址
九、动态分配二维数组为二维数组动态分配内存涉及几个问题:数组元素是否需要连续;数组是否规则。一个声明如下的二维数组所分配的内存是连续的(栈上连续):int matrix[2][5]={1,2,3,4,5},{6,7,8,9,10}};
不过,当我们用malloc这样的函数创建二维数组时,在内存分配上会有几种选择。由于我们可以将二维数组当做数组的数组,因而“内层”的数组没有理由一定要是连续的。如果对这种数组使用下标,数组的不连续对程序员是透明的。下面就是进行堆上数组内存分配1、分配不连续内存int rows=2;
int columns = 5;
int**matrix=(int**)malloc(rows*sizeof(int*));
for(inti=0;i<rows;i++)
{
matrix[i]=(int*)malloc(columns*sizeof(int));
}
内存示意图:1、分配不连续内存int rows = 2;
int columns = 5;
int**matrix=(int**)malloc(rows*sizeof(int*));
matrix [ 0 ] = ( int * ) malloc ( rows * columns * sizeof ( int ) ) ;
for (int i = 1 ; i < rows ; i + + )
{
matrix[i]=matrix[0]+i*columns;
}
内存示意图:十、不规则数组和指针其实不陌生;比如常用的就是二维不规则数组就是字符串组,每一行字符串长度都不同这个不太常用,一般不怎么用,到时候看自己需要我们用3个复合字面量声明不规则数组,然后从0开始按行-列顺序初始化数组元素。下面的代码片段会打印数组来验证创建是否正确,因为每行的列数不同,所以需要3个for循环:int(*(arr2[1))=
{
(int[]){0,1,2,3},
(int[]){4,5},
(int[]){6,7,8}
};
int row = 0;
for(int i=0;i<4;i++)
{
printf("Layer1[%d][%d] Address:%p Value:%d\n", row, i, &arr2[row][i], arr2[row][i]);
}
printf("\n");
row=1;
for(int i=0;i<2;i++)
{
printf("Layer1[%d][%d] Address:%p Value:%d\n", row,i,&arr2[row][i],arr2[row][i]);
}
printf("\n");
row=2;
for(int i=0;i&lt;3;i++)
{
printf("Layer1[%d][%d] Address:%p Value:%d\n", row,i,&arr2[row][i],arr2[row][i]);
}
printf("\n");
//输出
arr2[0][0] Address:0x000100 Value:0
arr2[0][1] Address: 0x000104 Value: 1
arr2[0][2] Address: 0x000108 Value: 2
arr2[0][3] Address: 0x000112 Value: 3
arr2[1][0] Address: 0x000116 Value: 4
arr2[1][1] Address: 0x000120 Value: 5
arr2[2][0] Address: 0x000124 Value: 6
arr2[2][1] Address: 0x000128 Value: 7
arr2[2][2] Address: 0x000132 Value: 8
内存布局:}

我要回帖

更多关于 创建一个3行4列的二维数组 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信