c语言中数组的地址
Ⅰ c语言数组首地址相关问题!!
若a是一维数组名,我们知道*a就是a[0],就是*(arr+0)。因为a是数组的首地址,*a就是取首地址所指元素,就是数组的第一个元素。
同样的道理,a是二维数组名时,*a也是取a的第一个元素,但是此时a所指的元素是一个一维数组,所以,实际上a所指元素是一维数组的首地址。
二维数组a,a是数组地址,指向行;有一个等价关系 a[i]=*(a+i)
a[i]指向列,&a[i]又指向行。
你可以将*和&理解为相反的操作:
a指向行,*(a+i)指向列,*(*(a+i)+j)等价于a[i][j];
就按a[3][4]这个例子来看:3行4列数组a可以理解为a[0],a[1],a[2]这三个一维数组
a[0][0] a[0][1] a[0][2] a[0][3]//第一行a[0][]
a[1][0] a[1][1] a[1][2] a[1][3]//第二行a[1][]
a[2][0] a[2][1] a[2][2] a[2][3]//第三行a[2][]
(数组含有4个元素)构成的二维数组,*a就是a[0],而a[0]就是第0行的首地址,也就是第一个数组的首地址。*(a+i)就是a[i],就是第i行的首地址。
如果现在定义a是字符型数组,输出*a(也就是第一行的首地址)为0000,再输出*(a+1)就是0004,而不是0001,就可以说明a是指向一维数组的指针。
Ⅱ 关于C语言数组的地址的疑问
当你写int a[5]时,编译器会分配sizeof(int) * 5的连续内存空间存放数组元素。数组名只是个常量,不占任何存储空间,它用名字a表示。打开反汇编看看,凡是用到数组名的地方都是都是直接写的地址值,而不是像变量那样通过访问一个内存地址获得数值,也就是说就是个立即数。
C的语法中有些东西可以在机器的层面上解释,有些要在编译器的层面上解释。a这个数组名就要在编译器的层面上解释,编译器把数组名和数组地址当成一个东西,它与变量名是指变量的值而不是地址不同。没有为什么,编译器就是这么对待数组名的,就像字符串变量名指的就是首字符地址一样,这是个规定。如果非要说为什么,那就是将a当作数组内容没有意义,例如,把a当作实参传入函数,只是传的数组地址,效率高,如果把a当作数组内容看待,那就意味着要把数组内容复制一份再传到函数里面了。
a和&a确实是一个值,因为a本身就是个常数没有地址,编译器并没有将&a当作错误处理,而是友好的将其翻译成a了。由于a是常数,你也不能给a再赋值了,而你写a=b也没问题,编译器还是会友好的通过,只是a的值并没有被改编而已。
你之所以会问a为什么等于&a的原因是你把“名字”和“变量”搞混了,对变量来说&变量是指变量的地址,而数组名本身是个名字不是变量,因此它也不能被赋值,你可以翻翻所有的C语言书没有将a称作数组变量的,它只是个数组名,真正的数组变量(其实称作数组指针)这么定义:int (*b)[5]; 你可以把a赋给b,通过(*b)[1]访问数组元素。看,真正的数组变量访问数组元素的方式都和数组名不同。
Ⅲ C语言中如何指定数组的首地址在指定的地址
据我所知,创建数组需要2个参数,1是地址,2是分配空间。空间分配是不能重复的,也就是说创建2个数组,这两个数组是不可能重合的,为了防止这种事情出现,所以不能指定地址。而是编译器自动分配,不能人为。
但是可以省去分配空间这个步骤,而是只创建地址,这就是指针的概念。比如int a[12],你若是想创建另一个代替a[12],可以int *p=a;这样,p的值就是a数组的首地址了。int *p =(int*)0x80000;意思就是p[0]的地址是0x80000,创建的时候要确定(int*)0x80000已经分配过了,可以使用了,不然就相当于野指针,容易出错。
Ⅳ C语言中的二维数组里a+1和*(a+1)为什么都是地址
在C语言中,二维数组由多个一维数组构成,数组名a指向第一个一维数组的首地址,仍为地址。表达式a+1中的a是二级指针,指向数组a[0]的一维数组(表示行),1表示行移动1位,因此a+1表示的是1行0列的地址。
而在*(a+1)中,a同样是二级指针,其值为指向一维数组的一级指针,即二维数组中的行。一级指针指向的一维数组只能通过行向下移动一位,所以*(a+1)就是第一行的首地址,也就是二维数组中第一行零列的地址。
举例来说,如果有一个二维数组A[3][4],按“行优先顺序”存储,其首元素A[0][0]的地址计算公式为:
LOC(A[0][0]) = LOC(A[0][0]) + ((0 - 0) * 4 + (0 - 0)) * t = LOC(A[0][0])
而A[1][0]的地址计算为:
LOC(A[1][0]) = LOC(A[0][0]) + ((1 - 0) * 4 + (0 - 0)) * t = LOC(A[0][0]) + 4 * t
如果按“列优先顺序”存储,则A[0][0]的地址计算公式为:
LOC(A[0][0]) = LOC(A[0][0]) + ((0 - 0) * 3 + (0 - 0)) * t = LOC(A[0][0])
A[0][1]的地址计算为:
LOC(A[0][1]) = LOC(A[0][0]) + ((0 - 0) * 3 + (1 - 0)) * t = LOC(A[0][0]) + t
存放该数组至少需要的单元数为(m-p+1) * (n-q+1) * t 个字节,其中m和n分别为数组的行数和列数,p和q为数组的起始下标,t为每个元素占用的字节数。
综上所述,a+1和*(a+1)在C语言中都指向二维数组的特定地址,但具体指向的地址不同,前者指向的是行的移动,后者指向的是行首地址。
(4)c语言中数组的地址扩展阅读:对于二维数组A[m][n],这是一个m行n列的二维数组。设a[p][q]为A的第一个元素,即二维数组的行下标从p到m+p,列下标从q到n+q。按“行优先顺序”存储时,元素a[i][j]的地址计算为:
LOC(a[i][j]) = LOC(a[p][q]) + ((i - p) * n + (j - q)) * t
按“列优先顺序”存储时,地址计算为:
LOC(a[i][j]) = LOC(a[p][q]) + ((j - q) * m + (i - p)) * t
存放该数组至少需要的单元数为(m-p+1) * (n-q+1) * t 个字节,其中m和n分别为数组的行数和列数,p和q为数组的起始下标,t为每个元素占用的字节数。
Ⅳ C语言中,数组在内存中占一片连续的存储区,由什么来代替它的首地址
C语言中规定,数组名就代表了该数组的首地址。
整个数组是以首地址开头的一块连续的内存单元。如有字符数组char c[10]。设数组c的首地址为2000,也就是说c[0]单元地址为2000。则数组名c就代表这个首地址。
因此在c前面不能再加地址运算符&。如写作scanf("%s",&c);则是错误的。在执行函数printf("%s",c) 时,按数组名c找到首地址,然后逐个输出数组中各个字符直到遇到字符串终止标志'