No More Confusing Pointers

2019-09-22 06:33发布

问题:

Following is my code:

#include <stdio.h>
int main()
{
     char a[10]="Hi!";  
    void f(char b[])
    {
        // 1. printf("*a is:%s\n",*a);
        printf("&a is:%p\n",&a);
        // 2. printf("&&a is:%p\n",&(&a));
        printf("a's address is:%p\n",a);
        printf("a's value is:%s\n",a);
        printf("b's address is:%p\n",b);
        printf("b's value is:%s\n",b);
        // 3. printf("*b is:%s\n",*b);
        printf("&b is:%s\n",&b);
    }

    f(a);

    return 1;
    getch();
}

Running the above code gives the output:

&a is:0028FF1C
a's address is:0028FF1C
a's value is:Hi!
b's address is:0028FF1C
b's value is:Hi!
&b is:∟ (

In the Output: Why are there different outputs for &a and &b; Although a and b have same reference.

Further,

I've mentioned 3 comments by their number. If I remove slashes one by one and execute them,I get following 2 issues:

  1. On executing comment no. 1 & 3:

    "abc.exe has stopped working."
    
  2. On executing comment no. 2:

    abc.c: In function 'f':
    abc.c:14:32: error: lvalue required as unary '&' operand
              printf("&&a is:%p\n",&(&a));
                            ^
    

回答1:

  • Point 1: Nested functions are not standard C. They are supported as GCC extension..

  • Point 2: printf("&b is:%s\n",&b); is wrong and invokes UB, because of improper format specifier. You need to change that to

     printf("&b is:%p\n",(void *)&b);
    
  • Point 3: &(&a) is wrong. the operand for & needs to be an lvalue, not another address, which is not an lvalue.

    Related: C11, chapter §6.5.3.2, for the operand type

    The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

    and the return type

    ....result is not an lvalue.



回答2:

You copy pasted the printf() and didn't change the specifier

printf("&b is:%s\n", &b)
/*             ^ should be `p' */

The first comment, when executed is causing a problem because you are using the "%s" specifier and passing the first character of a which will be interpreted as an address, try this

printf("*a is: %c\n", *a);

The third comment presents the same problem.

The second comment, you need an intermidiate pointer to do that, like

char  *c = &a;
char **d = &c;

printf("%p\n", (void *) d);

although it will print the same as printf("%p\n", (void *) a); because they all have the same address, the differenece is that the pointer arithmetic will work different.



回答3:

Well, you shouldn't define functions inside another function - though some compilers accept that (like gcc), it isn't portable.

    printf("&b is:%s\n",&b);

Here &b is the address of b, which is the address of the char array. In effect &b is the address of the parameter.

1.) and 3.) fail because you need to pass a pointer to a string. *a, is a dereferenced pointer, so, in effect, it's the first character of the string

2.) &&a is a pointer to a pointer to a pointer to a pointer (as a is already a pointer.



回答4:

Note: This is the question author's own answer, see revision 3


I understood the above issues and here's the improved code:

    #include<stdio.h>
    #include<string.h>

    int i;


    char a[11]="F*** Yeahh!";  //String : char *

    //'a' gets memory in "globals" area;'a' is a pointer to 'F'

    void func();//Function Definition

    int main()
    {
        func(a);    //Passing reference of 'a' to func
        getch();
        return 1;
    }

    void func(char b[])
        //'b' is given memory in 'stack' region;'b' has a reference
        // to 'a'   which in turn refer to 'F'
    {
        printf("*a is:%c\n",*a);
        printf("&a is:%p\n",&a);

        //printf("&&a is:%p\n",&(&a));//&()...Inside braces,there must be a
        // value..

        printf("a's address is:%p\n",a);
        printf("a's value is:%s\n",a);
        printf("b's address is:%p\n",b);
        printf("b's value is:%s\n",b);
        printf("*b is:%c\n",*b);
        printf("&b is:%p\n",&b);

        for(i=0;i<strlen(a);i++)
            printf("String as an array of characters is:%c\n",b[i]);
    }

Here's The Output:

*a is:F
&a is:00409000
a's address is:00409000
a's value is:F*** Yeahh!
b's address is:00409000
b's value is:F*** Yeahh!
*b is:F
&b is:0028FF20
String as an array of characters is:F
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:*
String as an array of characters is:
String as an array of characters is:Y
String as an array of characters is:e
String as an array of characters is:a
String as an array of characters is:h
String as an array of characters is:h
String as an array of characters is:!