C指向固定大小数组的现有指针
假设任何C函数都已经声明了一个指针,但还没有赋值。我们将使用int作为示例C指向固定大小数组的现有指针,c,arrays,pointers,C,Arrays,Pointers,假设任何C函数都已经声明了一个指针,但还没有赋值。我们将使用int作为示例 int *ptr; 该函数的目标不是在堆上分配任何动态内存,因此没有调用malloc。相反,我们希望它指向一个固定大小的数组n。我知道我可以这样做: int arr[n]; ptr = arr; 然而,如果我们需要在函数中多次这样做,代码可能会变得非常混乱和难以阅读,即,一个包含许多指针字段的结构都需要指向一个固定长度的数组。有没有更好的方法在一行中完成这一点?我在想下面类似的东西,但它看起来太模糊和不可编译:
int *ptr;
该函数的目标不是在堆上分配任何动态内存,因此没有调用malloc。相反,我们希望它指向一个固定大小的数组n
。我知道我可以这样做:
int arr[n];
ptr = arr;
然而,如果我们需要在函数中多次这样做,代码可能会变得非常混乱和难以阅读,即,一个包含许多指针字段的结构都需要指向一个固定长度的数组。有没有更好的方法在一行中完成这一点?我在想下面类似的东西,但它看起来太模糊和不可编译:
int *ptr;
// Many other things happen in between...
ptr[n];
***编辑***在这里,以下附加信息可能有助于指导更多的答案(不是说当前的答案不好)。在我的用例中,指针在结构中声明,在函数中,我将指针分配给数组。我想知道是否有比下面的代码(指向固定长度数组的所有指针)更简单的方法来实现这一点:
这似乎是一个明显的情况,你需要一些重构。使用类似的语句(通过传递对结构的引用和希望结构字段指向的数据),并为这个新函数指定一个有意义的名称
这可能比一些花哨的指针算术快捷方式更易于维护和阅读,你会在几周或几个月内忘记这些快捷方式。这似乎是一个明显的情况,你需要一些重构。使用类似的语句(通过传递对结构的引用和希望结构字段指向的数据),并为这个新函数指定一个有意义的名称
这可能比一些花哨的指针算术快捷方式更易于维护和阅读,你会在几周或几个月内忘记。在你的例子中,
ptr
和arr
之间的区别是你可以更改ptr
的值。所以我猜你想通过数组移动ptr
那么这个呢:
int arr[n], id=0;
您可以更改
id
的值,并将arr+id
用作ptr示例中ptr
和arr
之间的区别在于您可以更改ptr
的值。所以我猜你想通过数组移动ptr
那么这个呢:
int arr[n], id=0;
您可以更改id
的值,并使用arr+id
作为ptr
我想这样做的方法是使用宏。类似于(未经测试)
我不清楚为什么这会有帮助,我认为它可能“看起来很难看”,但如果没有宏,它会更容易维护。一般来说,隐藏您实际正在做的事情是一件坏事。我想这样做的方法是使用宏。类似于(未经测试)
我不清楚为什么这会有帮助,我认为它可能“看起来很难看”,但如果没有宏,它会更容易维护。通常,隐藏实际操作是一件坏事。不能在单个声明中声明数组并将其分配给现有指针。但是,可以将数组指针指定给新声明的指针,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
如果您坚持保持在一条直线内,您可以使用一个丑陋的宏,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
这一行的清晰度远远低于你文章中的两行版本,所以我会保留你的初始版本
编辑(回答问题编辑)
另一个选项是在声明中创建一个未使用的指针变量,并在初始值设定项中分配指针,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
不能在单个声明中声明数组并将其分配给现有指针。但是,可以将数组指针指定给新声明的指针,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
如果您坚持保持在一条直线内,您可以使用一个丑陋的宏,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
这一行的清晰度远远低于你文章中的两行版本,所以我会保留你的初始版本
编辑(回答问题编辑)
另一个选项是在声明中创建一个未使用的指针变量,并在初始值设定项中分配指针,如下所示:
int arr[n], *ptr = arr;
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
它不仅仅是含糊不清的——如果在运行时或编译时没有分配内存,它将/可能导致内存故障。为什么需要ptr
?为什么不直接使用arr
?@JamesMcLaughlin-他不喜欢它的样子。现在我也看到了你的编辑,出于好奇,我想问一下。你为什么要完成这个任务?另外,作为一种更简单的方法,我认为两行代码没有问题。两条线不重复。您可以按照下面的人给出的建议使用宏,但正如Hogan所说,宏只用于2行会造成更多的混乱。@update:只要数组在结构之前不超出范围,它就没有问题。(这在这里是正确的)它不仅仅是含糊不清的——如果在运行时或编译时没有分配内存,它将/可能导致内存故障。为什么需要ptr
?为什么不直接使用arr
?@JamesMcLaughlin-他不喜欢它的样子。现在我也看到了你的编辑,出于好奇,我想问一下。你为什么要完成这个任务?另外,作为一种更简单的方法,我认为两行代码没有问题。两条线不重复。您可以按照下面的人给出的建议使用宏,但正如Hogan所说,宏只用于2行会造成更多的混乱。@update:只要数组在结构之前不超出范围,它就没有问题。(这是正确的)