数组和指针的区别
- 数组内地址一定连续,指针则不一定连续。
- 数组赋值要么初始化就设定,要么循环元素赋值。而指针随时可以赋值(改变指向)。
- 数组的存储空间,不是在静态区就是在栈上。指针位置随意。
- sizeof(数组名)= 元素个数*sizeof(元素类型) 字节;而sizeof(指针) = 4字节(32位平台) 或 8字节(64位平台)
- 可以把二维数组数组名看作一个二级指针常量。链接
数组(名)是右值,而指针是左值?
例:
数组和指针是等效关系不是等价关系,一说指针对象,而数组非对象。
一维数组和指针很多时候可以通用如:
p[i] ⇔ *(p+i)
&p[i] ⇔ p+i
二维数组分配 ※
二维数组(指针)动态分配和释放
malloc工作只是开辟一块你要的内存(连续的),同时返回内存首字节的地址,但是他不限定你内存里的内容,malloc( 5*sizeof(char) ) 只是给你空出一段20字节的内存空间,并且给你他的首地址,而你实际要往内存里装什么,完全通过强制类型转换来限定,比如 int**p=(int**)malloc(n*sizeof(char*))
动态分配基本都要用到指针数组。
//二维都已知
char (*a)[N];//数组指针a = (char (*)[N])malloc(sizeof(char *) * m);printf("%d\n", sizeof(a)); //4,指针printf("%d\n", sizeof(a[0]));//N,一维数组free(a);
//二维未知
char **a;//二级指针int i;a = (char **)malloc(sizeof(char *) * m);//分配二级指针空间for(i=0; i<m; i++){a[i] = (char *)malloc(sizeof(char) * n); //分配一级指针空间,不保证a[0],a[1],...a[m]的值连续}printf("%d\n", sizeof(a)); //4,指针printf("%d\n", sizeof(a[0])); //4,指针for(i=0; i<m; i++){free(a[i]);}free(a);
//二维未知,连续内存
//法1(自上而下)
char **a;int i;a = (char **)malloc(sizeof(char *) * m);a[0] = (char *)malloc(sizeof(char) * m * n);//一次性分配所有空间for(i=1; i<m; i++){a[i] = a[i-1] + n;}//采用如上内存分配方法,意味着将a的值初始化为m*n的二维数组首地址,且这块内存连续printf("%d\n", sizeof(a)); //4,指针printf("%d\n", sizeof(a[0])); //4,指针free(a[0]);free(a);
//二维未知,连续内存
//法2(自下而上、逆向思维)double *Array1D=new double[n*m];double **Array2D=new double* [n];for(int i=0;i<n;i++){Array2D[i]=&Array1D[i*m];}delete[] Array2D[0];//或Array1Ddelete[] Array2D;
法2参考
两种方法的差异在于后者需要两个变量名,而第一种由于直接对元素赋值,中间指针数组并不需要命名。
注意内存的释放都是先释放低级的,再释放高级的。
此外,指针数组首地址不等于二维数组首地址,说明指针数组块和二维数组块不是重叠的,都有分配各自的空间。如图:
二维数组参数传递
传递的三种方法
指针的偏移量问题
-
指针的偏移量=指针的当前值+n*sizeof(指针指向的数据类型)
如 int (*a)[3]={0}; a是一个数组指针,a+1的偏移量是12个字节
又如 -
二维数组指针
int a[3][4],*p;
p=(int*)a;//将二维数组强制类型转化为一级指针,p++可以到12
左值和右值
左值(lvalue):一个标识非临时性对象的表达式。通常来说,可以将程序中所有带名字的变量看做左值。
右值(rvalue):相对的,右值标识是临时性对象的表达式,这类对象没有指定的变量名,都是临时计算生成的。
引用
(1)左值引用
左值引用的声明是通过在某个类型后放置一个符号&来进行的。前文代码中的int & y = x;便是一个左值引用。
需要注意的是,在定义左值引用时,=右边的要求是一个可修改的左值。
(2)右值引用(不常用)
类似于左值引用,右值引用便是对右值的引用,它是通过两个&&来声明的
引用和指针有什么区别
我们知道,指针是在内存中存放地址的一种变量,cpu能够直接通过而变量名访问唯一对应的内存单元,且每个内存单元的地址都是唯一的。
而变量名和引用,都可以看做内存的一个标签或是标识符,计算机通过是否符合标识符判断是否为目标内存,而一个内存可以有多个标识符
参考:https://www.cnblogs.com/Bylight/p/10530274.html