C语言中能否在函数外初始化指向类型化数组的指针?
问题解答
1. 取地址操作在全局域的可用性
你之前编译失败的根本问题,不是取地址&不能在函数外面用,而是你写的my_arr_ptr = &my_arr;是赋值语句——C语言规定,函数外部的全局域只能放变量声明/初始化代码,不能放这种运行时执行的赋值操作。
而你那个能正常编译的函数指针数组代码,是在声明数组的同时用&func_one做初始化,这是合规的:&func_one属于C标准允许的编译期就能确定值的常量表达式,完全可以用来初始化全局变量。
2. 全局域初始化指向类型化数组指针的正确方式
要在函数外面初始化my_arr_ptr,必须把声明和初始化合并起来写,直接在声明指针的时候赋值。
正确代码示例
#include <stdio.h> enum test_e { eONE, eTWO, eTHREE, }; typedef enum test_e test_t; #define NUMITEMS 12 // 直接在声明指针时初始化,绑定到my_arr的地址 test_t (*my_arr_ptr)[NUMITEMS] = &my_arr; // 定义全局数组 test_t my_arr[NUMITEMS] = { 0 }; int main() { // %p要求参数是void*,强制转换避免格式警告 printf("Hello World %p\n", (void*)my_arr_ptr); return 0; }
关键细节
- 全局变量的初始化值必须是编译期可确定的常量,
&my_arr符合要求:因为my_arr是全局数组,它的地址在编译阶段就已经固定了,编译器能直接把这个地址写入my_arr_ptr的初始化值里。 - 你之前错误代码里的
my_arr_ptr = &my_arr;单独放在全局域时,编译器会把它当成一个没有指定类型的新变量声明,默认按int处理,这就和之前声明的test_t (*)[12]类型冲突,才出现了那些报错——这和取地址操作本身没关系,纯粹是语法写法错了。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

