C中的二维数组和指针 - 如何访问元素?

时间:2012-06-24 12:24:54

标签: c pointers

我有一个涉及指向2D数组的指针的示例。有人可以帮我理解这个例子中发生了什么吗?

int main()
{

    int i = 0, j=0, sum0=0, sum1=0;
    int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}};
    int *Ptr;
    Ptr = *data;    //Why is the indirection operator used here? 
                    // Does Ptr = 23 by this assignment?

    for (i=0; i<4; i++) {
        sum1 = 0;
        for (j = 0; j < 3; j++) {
            sum1 += data[i][j];
        }
        if (sum1 > sum0) {
                 sum0 = sum1;
                 Ptr = *(data + i);     // Seems like this statement makes Ptr
        }                               // point one row below ... what syntax
    }                                   // can you use to access columns then?
                                       // Is it possible to use pointer arithmetic
    for (i=0; i<3; i++)                 // to access elements of data[i][j] that
        printf("%d\n", Ptr[i]);          // are not at j = 0?

  return 0;
}

5 个答案:

答案 0 :(得分:13)

data是一个2维数组,有4行,每行有3个元素(即4 X 3)。

现在,Ptr = *data;表示您将第一行的起始地址存储到指针变量Ptr。该陈述等同于Ptr = *(data + 0)Ptr = *(data + 1) - 这意味着我们正在分配第二行的起始地址。

然后*Ptr*(Ptr + 0)将为您提供指向的行的第一个元素的值。同样,*(Ptr + 1)将为您提供行的第二个元素的值。

程序中的for循环用于标识哪一行具有其元素总和的最大值(3个元素)。一旦控件来自for循环,Ptr将指向具有其元素的最大总和的行,sum0将具有该总和的值。

考虑一个数组int a[5];,我希望您知道a[0]0[a]是相同的。这是因为a[0]表示*(a+0)0[a]表示*(0 + a)。同样的逻辑可用于二维数组。

data[i][j]*(*(data + i) + j)类似。我们也可以将其写为i[data][j]

有关详细信息,请参阅yashwant kanetkar的“了解c中的指针”一书。

答案 1 :(得分:5)

Ptr = *data;*(data+0)+0的缩写,* (data+0)是第一行第一列元素的指针。添加数据的第一个0是行号,它是间接的并将我们带到第一行。 * (*(data+0)+0)仍然是一个地址,而不是它指向的值(对于2D数组)。因此,Ptr现在指向第一行中第一列的地址。第二个零是列号。因此,选择第一行和第一列的存储器地址。再次使用间接(*)只会给出地址所拥有的值。例如**data(*(p+i)+j)

通常,如果p是指针名称,i行号和j列号,

  1. *(*(p+i)+j)将给出2D数组中元素的内存地址。我排不了。和j是col no。,
  2. *(p+i)会给出该元素的值。
  3. *(p+i)将访问第i行
  4. 要访问列,请将列号添加到(*p)[columns]。您可能必须将指针声明为*p,而不仅仅是int *Ptr = *data。这样做,您将声明指向2D数组的指针。
  5. 使用指针运算是像二维数组那样处理二维数组。将指针* Ptr初始化为第一个元素(Ptr + n),然后添加一个no。 (public partial class Login : System.Web.UI.Page { string UserLogins = ConfigurationManager.ConnectionStrings["DB1"].ConnectionString.ToString(); public static object ConfigurationManager { get; private set; } protected void Page_Load(object sender, EventArgs e) { } protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) { Boolean blnresult; blnresult = false; blnresult = Authentication(Login1.UserName, Login1.Password); if (blnresult == true) { e.Authenticated = true; Response.Redirect("LandingPage.aspx"); } else { e.Authenticated = false; } } protected static Boolean Authentication(string usernames, string passwords) { string sqlcmd; sqlcmd = "SELECT UName, Pwd from [SignupDB] where UName = '" + usernames + "' and Pwd = '" + passwords + "'"; OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|/DB1.mdb;Persist Security Info=True;Jet OLEDB:Database Password=mypassword"); con.Close(); con.Open(); OleDbCommand cmd = new OleDbCommand(sqlcmd, con); OleDbDataReader reader; reader = cmd.ExecuteReader(); if (reader.Read()) return true; else return false; } } )访问列。添加高于列号的数字只会继续计算下一行第一列中的元素(如果存在)。

答案 2 :(得分:1)

data是一个由3个元素组成的整数数组。在期望“指向foo的指针”的上下文中,您可以使用“foo数组”,它的行为就像指向其第一个元素的指针,因此*data是指向{{1}的第一个元素的指针},即(可以这么说)data

所以,评论中第一个问题的答案:不,{23,55,50}不正确。 (可能不是; Ptr = 23Ptr而23是int *。)

{J} int使Ptr = *(data+i)指向Ptr的{​​{1}}行,这是正确的。更确切地说,i是一个3元素int数组的数组,其行为类似于指向int的3元素数组的指针;添加data会移过data个数组。

访问数组其他列的常用方法是普通数组索引。如果您引用i,则会收到第i行的data[i][j]列。如果你想用显式指针算术做,那么请注意示例代码中的(例如)j是“指向整数的指针”,所以i(例如)是任何元素的1行Ptr指向。 (但是,作为一种风格问题,当你实际上不需要时,通常不应该进行显式指针算法。)

答案 3 :(得分:0)

在你的例子中,循环遍历所有矩阵行,以找到所有元素之和保持最大值的那个。

在开始时,指定了指向第一行的指针:

Ptr = *data;

这意味着以下情况属实:

(Ptr[0] == 23 && Ptr[1] == 55 && Ptr[2] == 50)

请注意, Ptr 是一个指针,因此它包含一个内存地址,因此 Ptr 23 不同(除非内存地址发生在 23 ,这不太可能发生。)

答案 4 :(得分:0)

C允许多维数组,将它们作为连续位置存储在内存中,并且在幕后对地址算法进行更多处理。 考虑一个二维数组。

int arr [3] [3] = {{1,2,3},{4,5,6},{7,8,9}};

编译器将二维数组视为数组数组。 其中数组名称是指向数组中第一个元素的指针。 因此,arr指向第一个3元素数组,它实际上是二维数组的第一行(即行0)。 类似地,(arr + 1)指向第二个3元素数组(即第1行),依此类推。 该指针的值(arr + 1)指向整个行。 由于第1行是一维数组,(arr + 1)实际上是指向第1行中第一个元素的指针。 现在将2添加到该指针。因此,((arr + 1)+ 2)是第1行中元素2(即第三个元素)的指针。该指针的值(arr + 1 )+ 2),指的是第1行第2列中的元素。