简体   繁体   中英

How can I test the -> C operator using a struct that allows me to access a struct's field?

I'm trying to test the -> operator, but I can't seem to do that, because when I execute the following program and feed the input with a stream, the program stops working.

Note1: I get a warning before compiling, it says that:

format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat=]

Note2: if I omit the line printf("%s\\n", *(&home1)->name ) , it works just fine, and actually prints whatever I wrote.

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

typedef struct home_type {
    char name[30] ;
}home;

int main (void) {
    home home1 ;
    char name[30] ;
    scanf ("%[^\n]%*c", name);
    strcpy( home1.name, name) ;
    printf("%s\n", home1.name ) ;
    printf("%s\n", *(&home1)->name ) ;
    return 0 ;
}

Remove * and it works. Your code *(&home1)->name is analogous to *(home1.name) eg instead of passing the pointer to the first character, it passes the value of the first char in name ; due to default argument promotions, that value is converted into an int .

Thus:

printf("%s\n", (&home1)->name );

should work; however you don't need -> here; -> is now just a shortcut for using a pointer-to-structs more conveniently; ie (*ptr).name into a more palatable ptr->name ; as home is already a struct and not just a pointer to struct, you should use the . instead.

You just have to drop the * (ie not dereference):

printf("%s\n", (&home1)->name );

The member name is an array which gets converted into a pointer ( char* ) when passing to printf() . However, when you dereference it, it's just a single char that you pass. Obviously, it doesn't match with what printf() expects for the format %s .

See: What is array decaying?

Operators -> and . are interchangeable:

  • obj.field is the same as (&obj)->field
  • ptr->field is the same as (*ptr).field

Note that you have added an asterisk to the result of (&home1)->name , which produces a char . Since printf is a variable-argument function, char is promoted to int during the call, explaining the warning.

When you pass an int for a parameter expecting a pointer, undefined behavior happens; in your case, the program crashes. Removing the dereference operator * will fix this problem.

(&home1)->name is the member array. *(&home1)->name is a dereference on the member array which because of array decay is equivalent to (&home1)->name[0] . This has type char . Passing a char through the ... of a variadic function such as printf promotes it to int ( ... causes default argument promotions to apply).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM