我有以下C代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
#define ARRAYSIZEWITHPTR(a) (&(a)[1] - a)
int main (void){
int array[5] = {1,2,3,4,5};
int* pArray = array;
int* p = calloc(ARRAYSIZE(array), sizeof(int));
assert(NULL != p);
printf("size of array: %ld\n", ARRAYSIZE(array));
printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
printf("size of p: %ld\n", ARRAYSIZE(p));
printf("size of pArray: %ld\n", ARRAYSIZEWITHPTR(pArray));
printf("size of p: %ld\n", ARRAYSIZEWITHPTR(p));
free(p);
return 0;
}
当我编译这个程序时,我从GCC那里收到了以下警告消息:
test.c: In function ‘main’:
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
| ^
test.c:15:35: note: in expansion of macro ‘ARRAYSIZE’
15 | printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
| ^~~~~~~~~
test.c:11:8: note: first ‘sizeof’ operand was declared here
11 | int* pArray = array;
| ^~~~~~
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
| ^
test.c:16:30: note: in expansion of macro ‘ARRAYSIZE’
16 | printf("size of p: %ld\n", ARRAYSIZE(p));
| ^~~~~~~~~
test.c:12:8: note: first ‘sizeof’ operand was declared here
12 | int* p = calloc(ARRAYSIZE(array), sizeof(int));
| ^
以下是程序输出:
size of array: 5
size of pArray: 2
size of p: 2
size of pArray: 1
size of p: 1
从程序输出中可以明显看出,只有在以数组名称作为参数调用宏时,我才能获得正确的值.然而,数组名称不是指向数组的第一个元素的指针吗?如果是这样的话,使用数组名称调用宏(这样会产生正确的结果)与指向堆上的数组的指针(不会产生正确的结果)之间有什么本质的区别?
从源代码中可以看出,我try 了两种宏方法来获取在堆上创建的数组的大小,但都没有成功.
那么下一个问题是,在C编程中使用calloc(
)在堆上这样创建的数组的大小是不是可能的?
提亚