C语言数组地址问题

如果有 a[3][4],我想调用它的地址,这些都是什么?
&a ,*a, a, a[0], *a[0], a[2] , &a[2],&a[2][2]
救命啊

解释如下:

&a,*a,a,a[0]——都表示的是数组第0行第0个元素的地址;

*a[0]——这个特殊,表示第0行第0个元素的地址的地址;

a[2],&a[2]——都表示第2行第0个元素的地址;

&a[2][2]——表示第2行第2个元素的地址;

详见图片,我已经把数组中主要元素的地址和值都打印出来了,数组中对应的每个元素的地址写出来了,对照的找下对应元素的位置,应该能理解&a,*a,a,a[0],*a[0],a[2],&a[2],&a[2][2]是什么意思了

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[3][4] = {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            };

    printf("&a十六进制地址是%p,十进制是%d\n",&a,&a); //数组名,a[3][4]
    printf("*a十六进制地址是%p,十进制是%d\n",*a,*a);
    printf("a十六进制地址是%p,十进制是%d\n",a,a);
    printf("a[0]十六进制地址是%p,十进制是%d\n",a[0],a[0]);
    printf("*a[0]十六进制地址是%p,十进制是%d\n",*a[0],*a[0]);
    printf("a[2]十六进制地址是%p,十进制是%d\n",a[2],a[2]);
    printf("&a[2]十六进制地址是%p,十进制是%d\n",&a[2],&a[2]);
    printf("&a[2][2]十六进制地址是%p,十进制是%d\n",&a[2][2],&a[2][2]);

    printf("数组a[3][4]首元素a[0][0]的地址是%p,首元素a[0][0]的值=:%d\n",&a[0][0],a[0][0]);
    printf("数组a[3][4]首元素a[2][0]的地址是%p,首元素a[2][0]的值=:%d\n",&a[2][0],a[2][0]);
    printf("数组a[3][4]首元素a[2][2]的地址是%p,首元素a[2][2]的值=:%d\n",&a[2][2],a[2][2]);
    printf("一个int整型变量占的字节是:%d",sizeof(int));
    return 0;
}

追问

呃,能看清楚不,我这个程序是要找出3*4数组中最大的值并输出下标,但是我输入的值和调试程序中得到的值不同,是不是我调用函数里面的东西不对啊

追答

下面是修改后的代码,应该能理解吧

#include <stdio.h>

void max(int * p, int m, int n); //int v[] 是一个地址,所以改为指针(看之前我回复你的)
int main()
{
int a[3][4],i,j;
int *p;
    printf("请输入一个3行4列的数组:\n");
for(i=0; i<3; i++)
{
for(j=0; j<4; j++)
{
scanf("%d",&a[i][j]); //动态输入3行4列的二维数组
}
}
p = &a[0][0];   //定义指针,指向数组a的首元素。
max(p,3,4);  //a[3]使用指针p代替

return 0;
}
void max(int * p, int m, int n)
{
int i,j,m1,p1,q1; //i,j循环变量,m1存储最大数值,p1存储行坐标,q1存储列坐标
//m1 = v[0]; //m1 = v[0]这里应该报错
m1 = *p; //把第一个元素值给m1存储起来
for(i=0; i<m; i++)
{
for(j=0; j<n; j++) //q=0开始比较
{
if( *((p+i)+j) > m1 ) //if()后面的分号去掉,否则是执行分号的.v[p][q]写成这样不是更好理解么
{
m1 = *((p+i)+j);
p1 = i;
q1 = j;
}
}
}
printf("最大值为%d  ,下标为v[%d][%d]",m1,p1,q1);
}

追问

您的程序输出最大值为6?我按照您说的改了,最大值成0了。

追答

#include void max(int * p, int m, int n); //int v[] 是一个地址,所以改为指针(看之前我回复你的)int main(){ int a[3][4],i,j; int m1,p1=0,q1=0;//i,j循环变量,m1存储最大数值,p1存储行坐标,q1存储列坐标 printf("请输入一个3行4列的数组:\n"); for(i=0; i m1 ) //if()后面的分号去掉,否则是执行分号的.v[p][q]写成这样不是更好理解么 { m1 = a[i][j]; p1 = i; q1 = j; //printf("最大值为%d ,下标为v[%d][%d]\n",m1,p1,q1);//调试使用 } } } printf("最大值为%d ,下标为v[%d][%d]",m1,p1,q1); return 0;}

调用函数的方法我在想想,调用函数中取值出现错误,如下面的图

调用函数的搞定了,形参定义成行指针数组就好了

#include void max(int (*ptr)[4], int m, int n); //int v[] 是一个地址,所以改为指针(看之前我回复你的)int main(){ int a[3][4],i,j; int (*p)[4]; //定义行指针 printf("请输入一个3行4列的数组:\n"); for(i=0; i m1 ) //if()后面的分号去掉,否则是执行分号的.v[p][q]写成这样不是更好理解么 { m1 = *(*(ptr+i)+j); p1 = i; q1 = j; } //printf("u最大值为%d ,下标为v[%d][%d]\n",m1,p1,q1); } //printf("u最大值为%d ,下标为v[%d][%d]\n",m1,p1,q1); } printf("最大值为%d ,下标为a[%d][%d]",m1,p1,q1); }

追问

好的,我再想一想

温馨提示:答案为网友推荐,仅供参考
第1个回答  2018-12-14

首先a[3][4]的地址是&a[3][4]

然后再回答你接下来的问题:

我设置了a[10][10]的数组

根据这个可以看出&a ,*a, a都表示第一个这个数组的首地址

a[0]表示a[0]这一行的首地址

*a[0],表示这一行的首值

a[2],&a[2]表示a[2]行的首地址

&a[2][2]表示a[2][2]的地址