about the expression “&anArray” in c

后端 未结 3 1782
Happy的楠姐
Happy的楠姐 2021-01-16 18:18

First, I read that:

  • array
  • &array
  • &array[0]

will all be the same as long as \"ar

3条回答
  •  失恋的感觉
    2021-01-16 18:45

    If your code compiled without warnings, you are not making full use of your compiler. It will help you if you ask it to do so. Learn how to make it compile with warnings, and learn how to fix the problems it diagnoses. I compiled the code below with one or the other of these commands:

    gcc -O3 -g -std=c99 -Wall -Wextra -m64 array-stuff.c -o array-stuff
    gcc -O3 -g -std=c99 -Wall -Wextra -m32 array-stuff.c -o array-stuff
    

    That's a good starting point for clean code with GCC. Indeed, -Wall without -Wextra is pretty good too.

    Here's an adaptation of your code (in a file array-stuff.c) — although most of it is different:

    #include 
    #include 
    
    int main(void)
    { 
        // DC4M = Doesn't compile for me, because I compile with stringent warnings
        char ar[16] = { 'a', 'b', 'c', '\0' };  // Note explicit size
        printf("%-18s  %s\n", "Code:", "char ar[16] = { 'a', 'b', 'c', '\0' };");
        //printf("argument: &ar     %s\n", &ar);    // DC4M
        printf("argument: &ar[1]  %s\n", &ar[1]);
    
        printf("%-18s  0x%" PRIXPTR "\n", "ar:",       (uintptr_t)ar);
        printf("%-18s  0x%" PRIXPTR "\n", "&ar:",      (uintptr_t)&ar);
        printf("%-18s  0x%" PRIXPTR "\n", "(ar+1):",   (uintptr_t)(ar+1));
        printf("%-18s  0x%" PRIXPTR "\n", "(&ar+1):",  (uintptr_t)(&ar+1));
        printf("%-18s  0x%" PRIXPTR "\n", "&ar[1]:",   (uintptr_t)(&ar[1]));
        printf("%-18s  0x%" PRIXPTR "\n", "&(ar[1]):", (uintptr_t)(&(ar[1])));
        printf("%-18s  0x%" PRIXPTR "\n", "(&ar)[1]:", (uintptr_t)((&ar)[1]));
    
        printf("%-18s  %zu\n", "sizeof(ar):",       sizeof(ar));
        printf("%-18s  %zu\n", "sizeof(&ar):",      sizeof(&ar));
        printf("%-18s  %zu\n", "sizeof(void*):",    sizeof(void*));
        printf("%-18s  %zu\n", "sizeof(ar[1]):",    sizeof(ar[1]));
        printf("%-18s  %zu\n", "sizeof(&ar[1]):",   sizeof(&ar[1]));
        printf("%-18s  %zu\n", "sizeof(&(ar[1])):", sizeof(&(ar[1])));
        printf("%-18s  %zu\n", "sizeof((&ar)[1]):", sizeof((&ar)[1]));
    
        {
        char  a = 's';
        char *pa = &a;
        printf("%-18s  %s\n", "Code:", "char  a = 's';");
        printf("%-18s  %s\n", "Code:", "char *pa = &a;");
        //printf("argument: &pa   %c\n", &pa);    // DC4M
        printf("%-18s  0x%" PRIXPTR "\n", "&pa:",  (uintptr_t)&pa);
        printf("%-18s  0x%" PRIXPTR "\n", "&a:",   (uintptr_t)&a);
        printf("%-18s  0x%" PRIXPTR "\n", "pa:",   (uintptr_t)pa);
        }
    
        {
        char  *pa = &ar[0];
        char **ppa = &pa;
        //printf("argument: &pa   %s\n", ppa);  // DC4M
        printf("%-18s  %s\n", "Code:", "char  *pa = &ar[0];");
        printf("%-18s  %s\n", "Code:", "char **ppa = &pa;");
    
        printf("%-18s  0x%" PRIXPTR "\n", "&pa:",  (uintptr_t)&pa);
        printf("%-18s  0x%" PRIXPTR "\n", "ppa:",  (uintptr_t)ppa);
        printf("%-18s  0x%" PRIXPTR "\n", "*ppa:", (uintptr_t)*ppa);
        printf("%-18s  0x%" PRIXPTR "\n", "&ppa:", (uintptr_t)&ppa);
        }
    
    }
    

    This is the output from a Mac OS X 10.7.4 machine with a 64-bit compilation:

    Code:               char ar[16] = { 'a', 'b', 'c', '
    argument: &ar[1]  bc
    ar:                 0x7FFF6C9DE570
    &ar:                0x7FFF6C9DE570
    (ar+1):             0x7FFF6C9DE571
    (&ar+1):            0x7FFF6C9DE580
    &ar[1]:             0x7FFF6C9DE571
    &(ar[1]):           0x7FFF6C9DE571
    (&ar)[1]:           0x7FFF6C9DE580
    sizeof(ar):         16
    sizeof(&ar):        8
    sizeof(void*):      8
    sizeof(ar[1]):      1
    sizeof(&ar[1]):     8
    sizeof(&(ar[1])):   8
    sizeof((&ar)[1]):   16
    Code:               char  a = 's';
    Code:               char *pa = &a;
    &pa:                0x7FFF6C9DE560
    &a:                 0x7FFF6C9DE56F
    pa:                 0x7FFF6C9DE56F
    Code:               char  *pa = &ar[0];
    Code:               char **ppa = &pa;
    &pa:                0x7FFF6C9DE558
    ppa:                0x7FFF6C9DE558
    *ppa:               0x7FFF6C9DE570
    &ppa:               0x7FFF6C9DE550
    

    And this is the output from a 32-bit compilation:

    Code:               char ar[16] = { 'a', 'b', 'c', '
    argument: &ar[1]  bc
    ar:                 0xC008A670
    &ar:                0xC008A670
    (ar+1):             0xC008A671
    (&ar+1):            0xC008A680
    &ar[1]:             0xC008A671
    &(ar[1]):           0xC008A671
    (&ar)[1]:           0xC008A680
    sizeof(ar):         16
    sizeof(&ar):        4
    sizeof(void*):      4
    sizeof(ar[1]):      1
    sizeof(&ar[1]):     4
    sizeof(&(ar[1])):   4
    sizeof((&ar)[1]):   16
    Code:               char  a = 's';
    Code:               char *pa = &a;
    &pa:                0xC008A668
    &a:                 0xC008A66F
    pa:                 0xC008A66F
    Code:               char  *pa = &ar[0];
    Code:               char **ppa = &pa;
    &pa:                0xC008A664
    ppa:                0xC008A664
    *ppa:               0xC008A670
    &ppa:               0xC008A660
    

    When you understand how the various numbers were arrived at, you will be well on your way to understanding things.

    Note that &array[1] is interpreted as &(array[1]); it is different from (&array)[1] in type and size. The postfix operators such as array subscripting bind more tightly than the unary operators such as the address (&) and indirection (*) operators.

提交回复
热议问题