对于函数:void foo(char (*argv1)[3], char *argv2[3])
来说:
char (*argv1)[3]
是数组的指针,编译器知道数组的大小char *argv2[3]
是指针的数组,编译器不知道数组的大小,会退化为char **argv2
如图所示:
void foo(char (*argv1)[3], char *argv2[3])
{
sizeof(argv1); // 8
sizeof(argv2); // 8
sizeof(*argv1); // 3
sizeof(*argv2); // 8
}
char (*)[3]
是一种类型:
typedef char (*arr_3_ptr_t)[3];
这种类型可以用于传递一些定长数组,例如:
#define JMP_INS_SIZE 5
typedef unsigned char ins_backup_t[JMP_INS_SIZE];
/**
* @brief 动态打桩函数
* @param [in]old_func 需要被替换的函数
* @param [in]new_func 要替换成什么函数
* @param [out]buff 备份原函数入口处的指令
*/
void stub(void* old_func, void* new_func, ins_backup_t *backup)
{
/// ...
memcpy(*backup, olf_func, sizeof(*backup));
/// ...
}
int main()
{
ins_backup_t malloc_backup;
stub(malloc, my_malloc, &malloc_backup);
}
使用typedef struct acc acc_t[1]
的好处
这就是数组的两头都占好的特性吧,定义时候能直接分配好地址,使用的时候还能把数组名当指针用。
对比:
typedef struct acc acc_t[1]
void foo(struct acc*);
// 1. 使用原始写法
struct acc acc1;
foo(&acc);
// 2. 使用这个技巧
acc_t acc2;
foo(acc2);
数组的一个坑
int main()
{
int acc[1];
printf("%d\n", acc);
printf("%d\n", &acc);
}
// 结果相同:
-42946092
-42946092
就你妈离谱