对c指针赋值有些困惑
having some confusion about c pointer assignment
我在思考 C 中的指针赋值时遇到了一些麻烦。星号字符出现在许多不同的位置,我不明白为什么我会选择使用一种方式而不是另一种方式。
具体在下面的代码中:
我为什么会选择:
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
超过:
conn->db->rows = (struct **Address)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
在 sizeof 中,星号表示什么?
这就是上面代码的由来。不是整个程序。
struct Address {
int id;
int set;
char *name;
char *email;
};
struct Database {
int MAX_DATA;
int MAX_ROWS;
struct Address **rows; // USE ARRAY OF POINTERS
};
struct Connection {
FILE *file;
struct Database *db;
};
void die(const char *message) {
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
void Address_print(struct Address *addr) {
printf("%d %s %s\n", addr->id, addr->name, addr->email);
}
void Database_load(struct Connection *conn) {
size_t i=0;
// Each database will have two `int` values. read
// those first.
assert(conn->db && conn->file);
if (!(conn->db && conn->file))
die("Database load : Invalid Connection info");
if (fread(&conn->db->MAX_DATA, sizeof(conn->db->MAX_DATA), 1, conn->file) != 1)
die("Database load : Couldn't read MAX_DATA");
if (fread(&conn->db->MAX_ROWS, sizeof(conn->db->MAX_ROWS), 1, conn->file) != 1)
die("Database load : Couldn't read MAX_ROWS");
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
assert(conn->db->rows);
if (!(conn->db->rows)) {
die("Database_load : Could not MAX_ROWS Address structures");
}
struct **Address
是非法语法。基本类型是 struct Address
,在 struct
关键字和 标签 、Address
之间应该只有空格(注释算作空格)。
struct Address *
是一个指向 struct Address
.
的类型
struct Address **
是一个指向 struct Address
.
的指针的类型
sizeof
表达式确定类型的大小(以字节为单位)。有两种形式:
sizeof(
type)
(对于某些类型,type)直接指定类型。
sizeof
expression(对于某些表达式,expression)使用结果类型 expression 而不评估 expression.
在sizeof(struct Address *)
的情况下,使用第一种形式。这被评估为 struct Address *
类型(指向 struct Address
的指针)的大小(以字节为单位)。
在声明中:
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
调用 malloc
的结果是一个通用指针类型 void *
并且它被 cast 运算符 (struct Address**)
以匹配分配给 rows
成员的类型。
在 C 中,通常的做法是在将 void *
值分配给另一个对象指针类型时省略强制转换,反之亦然。该语句可以重写,省略转换,如:
conn->db->rows = malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
此外,sizeof(
type)
的 type 操作数可以用具有以下表达式的表达式替换同一类型。由于 conn->db->rows
的类型为 struct Address**
,因此 *conn->db->rows
或 conn->db->rows[0]
的类型为 struct Address *
。这些中的任何一个都可以替换到语句中,将其重写为,例如:
conn->db->rows = malloc(sizeof(*conn->db->rows) * conn->db->MAX_ROWS);
这比直接在 sizeof
表达式中指定类型更不容易出错,并且是常见的做法。
我在思考 C 中的指针赋值时遇到了一些麻烦。星号字符出现在许多不同的位置,我不明白为什么我会选择使用一种方式而不是另一种方式。
具体在下面的代码中:
我为什么会选择:
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
超过:
conn->db->rows = (struct **Address)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
在 sizeof 中,星号表示什么?
这就是上面代码的由来。不是整个程序。
struct Address {
int id;
int set;
char *name;
char *email;
};
struct Database {
int MAX_DATA;
int MAX_ROWS;
struct Address **rows; // USE ARRAY OF POINTERS
};
struct Connection {
FILE *file;
struct Database *db;
};
void die(const char *message) {
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
void Address_print(struct Address *addr) {
printf("%d %s %s\n", addr->id, addr->name, addr->email);
}
void Database_load(struct Connection *conn) {
size_t i=0;
// Each database will have two `int` values. read
// those first.
assert(conn->db && conn->file);
if (!(conn->db && conn->file))
die("Database load : Invalid Connection info");
if (fread(&conn->db->MAX_DATA, sizeof(conn->db->MAX_DATA), 1, conn->file) != 1)
die("Database load : Couldn't read MAX_DATA");
if (fread(&conn->db->MAX_ROWS, sizeof(conn->db->MAX_ROWS), 1, conn->file) != 1)
die("Database load : Couldn't read MAX_ROWS");
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
assert(conn->db->rows);
if (!(conn->db->rows)) {
die("Database_load : Could not MAX_ROWS Address structures");
}
struct **Address
是非法语法。基本类型是 struct Address
,在 struct
关键字和 标签 、Address
之间应该只有空格(注释算作空格)。
struct Address *
是一个指向 struct Address
.
struct Address **
是一个指向 struct Address
.
sizeof
表达式确定类型的大小(以字节为单位)。有两种形式:
sizeof(
type)
(对于某些类型,type)直接指定类型。sizeof
expression(对于某些表达式,expression)使用结果类型 expression 而不评估 expression.
在sizeof(struct Address *)
的情况下,使用第一种形式。这被评估为 struct Address *
类型(指向 struct Address
的指针)的大小(以字节为单位)。
在声明中:
conn->db->rows = (struct Address**)malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
调用 malloc
的结果是一个通用指针类型 void *
并且它被 cast 运算符 (struct Address**)
以匹配分配给 rows
成员的类型。
在 C 中,通常的做法是在将 void *
值分配给另一个对象指针类型时省略强制转换,反之亦然。该语句可以重写,省略转换,如:
conn->db->rows = malloc(sizeof(struct Address *) * conn->db->MAX_ROWS);
此外,sizeof(
type)
的 type 操作数可以用具有以下表达式的表达式替换同一类型。由于 conn->db->rows
的类型为 struct Address**
,因此 *conn->db->rows
或 conn->db->rows[0]
的类型为 struct Address *
。这些中的任何一个都可以替换到语句中,将其重写为,例如:
conn->db->rows = malloc(sizeof(*conn->db->rows) * conn->db->MAX_ROWS);
这比直接在 sizeof
表达式中指定类型更不容易出错,并且是常见的做法。