我写了以下程序。

#include<windows.h>
#include <stdio.h>
#include<tchar.h>

#define MAX_ARG 5
#define MAX_COMMAND_LINE 10

int _tmain(int argc, LPTSTR argv[]){

BOOL exitFlag = FALSE;
TCHAR command[MAX_COMMAND_LINE], *pc;
DWORD i, localArgc;
TCHAR argstr[MAX_ARG][MAX_COMMAND_LINE] = {"abcdef", "Dravid", "sachin", "ganguli" };

char name[10] = "Happy";

// Why argstr == argstr[0]
printf("%p   %p \n", name,  name[0] );      // name != name[0]
printf("%p  %p = %p\n", argstr, argstr[0], *argstr);


// Why there is no difference if it increase left or right variable value?
TCHAR *place = malloc(10 * sizeof(TCHAR *));
place = argstr[0];
printf("%c  %c \n", *++place, *place ); // Incremented the left parameter
printf("%c  %c \n", *place, *++place ); // Incremented the right parameter

return 0;
}

1)为什么argstr==argstr[0]?
2)在printf中,从哪一侧(右/左)进行计算?

最佳答案

首先,根据您的声明,argstr在内存中的布局如下:

        +---+
argstr: |'a'| argstr[0][0]
        +---+
        |'b'| argstr[0][1]
        +---+
        |'c'| argstr[0][2]
        +---+
         ...
        +---+
        |'f'| argstr[0][5]
        +---+
        | 0 | argstr[0][6]
        +---+
         ...
        +---+
        | ? | argstr[0][9]
        +---+
        |'D'| argstr[1][0]
        +---+
        |'r'| argstr[1][1]
        +---+
         ...
        +---+
        | ? | argstr[1][9]
        +---+
        |'s'| argstr[2][0]
        +---+
         ...
        +---+
        | ? | argstr[4][9]
        +---+

所有50个数组元素都按行主顺序顺序排列(即,第一行的所有元素,然后是第二行的所有元素,等等)。注意,没有为任何地方的指针预留存储空间。这意味着第一子阵列的第一个元素的地址(&argstr[0][0])与数组的第一个元素的地址(&argstr[0])相同,后者与数组的地址(&argstr)相同。
除非它是sizeof或一元&运算符的操作数,或是用于在声明中初始化另一个数组的字符串文字,否则“N-element array ofT”类型的表达式将转换为“pointer toT”类型的表达式(“decay”,表达式的值将是数组第一个元素的地址。
在您的printf调用中,表达式argstr具有类型“5-element array of 10 element array ofTCHAR”。由于它不是sizeof或一元&运算符的操作数,因此它被转换为“指向TCHAR”或TCHAR (*)[10]的10元素数组的指针”类型的表达式,并且表达式的值是第一个元素(&argstr[0])的地址。
在同一调用中,表达式argstr[0]具有类型“10 element array ofTCHAR”。因为它不是sizeof或一元&运算符的操作数,所以它被转换为“pointer toTCHAR”或TCHAR *类型的表达式,并且表达式的值是第一个元素(&argstr[0][0])的地址。
我勒个去?为什么数组表达式的类型会变成指针?
数组下标运算符[]是根据指针算法定义的:表达式a[i]定义为*(a + i)。给定一个地址a,从该地址偏移i元素(不是字节)并取消对结果的引用。这是从B语言派生的C语言的继承。在B中,作为数组定义的一部分创建了一个单独的指针;该指针将绑定到数组名称并指向数组的第一个元素,因此在B&argstr&argstr[0]中确实会有所不同。
里奇在设计C时去掉了数组指针,但他想保留B的数组语义,所以他创建了上面的数组转换规则。在类似于argstr[i][j]的表达式中,子表达式argstr首先转换为指针值,该指针值用[i]下标;这将为我们提供另一个数组表达式,该数组表达式转换为新的指针表达式,该指针表达式用[j]下标。
综上所述,考虑到声明TCHAR argstr[5][10],以下所有内容都是正确的:
    Expression        Type              Decays to        Value
    ----------        ----              ---------        -----
        argstr        TCHAR [5][10]     TCHAR (*)[10]    Address of argstr[0]
       &argstr        TCHAR (*)[5][10]  n/a              Address of argstr
       *argstr        TCHAR [10]        TCHAR *          Value of argstr[0]
     argstr[i]        TCHAR [10]        TCHAR *          Address of argstr[i][0]
    &argstr[i]        TCHAR (*)[10]     n/a              Address of argstr[i]
    *argstr[i]        TCHAR             n/a              Value of argstr[i][0]
  argstr[i][j]        TCHAR             n/a              Value of argstr[i][j]
 &argstr[i][j]        TCHAR *           n/a              Address of argstr[i][j]

argstr&argstr*argstrargstr[0]&argstr[0]&argstr[0][0]都产生相同的值(数组第一个元素的地址),但表达式的类型不同。

09-16 08:40