对于函数: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); // 8sizeof(argv2); // 8sizeof(*argv1); // 3sizeof(*argv2); // 8}
char (*)[3] 是一种类型:
typedef char (*arr_3_ptr_t)[3];
这种类型可以用于传递一些定长数组,例如:
#define JMP_INS_SIZE 5typedef 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
就你妈离谱
