标量初始值设定项的多余元素,用于指向int数组的指针

时间:2011-11-12 23:40:24

标签: c arrays pointers

我正在K& R(例如5-9)进行练习,我试图转换原始程序的2D数组

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

使用指向13个整数的数组的指针,如

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

但编译器打印 警告:标量初始化程序中的多余元素

谷歌搜索没有帮助,甚至K& R在将数组传递给函数时写道,

myFunction(int daytab[2][13]) {...}

相同
myFunction(int (*daytab)[13]) {...}

3 个答案:

答案 0 :(得分:28)

这两者只是部分相同。区别在于:

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

声明一个二维数组,其中包括为数组预留空间并确保daytab引用该内存。但是:

static char (*daytab)[13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

...只声明一个指针。因此,您尝试使用数组初始值设定项初始化指针,该指针无法按预期工作。没有阵列;没有为阵列预留内存。相反的是,初始化程序中的第一个数字被分配给指针daytab,编译器会生成一个警告,告诉您已经指定了许多刚丢弃的附加值。由于初始值设定项中的第一个数字为0,因此您只需将daytab设置为NULL即可。{/ p>

因此,如果您想进行此类初始化,请使用第一个版本 - 它会衰减到您在第二个版本中明确声明的相同指针类型,因此您可以使用相同的方式。当您希望动态分配数组或获取对已存在的另一个数组的引用时,需要带有数组指针的第二个版本。

所以你可以这样做:

static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;

ptr = arr;

...然后互换使用ptrarr。或者这个:

static char (*ptr)[3] = NULL;

ptr = malloc(2 * sizeof(*ptr));

...获得一个动态分配的二维数组(不是指向1D数组的指针数组,而是一个真正的2D数组)。当然,在这种情况下它没有初始化。

两个变体的“等价”仅意味着当2D数组衰减到指向其第一个元素的指针时,它会衰减到第二个变体中声明的指针类型。一旦指针版本实际指向数组,两者是等价的。但是2D数组版本为数组设置了内存,其中指针声明没有...并且可以为指针指定一个新值(指向不同的数组),而2D数组变量则不能。

在C99中你可以做到这一点(至少不是static):

char (*daytab)[13] = (char [][13]){
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

答案 1 :(得分:1)

@Dmitri解释得很好,但我想补充一点

static char (*daytab)[13] = { ... };

是指向13个char元素数组的一个指针。编译器会向您发出警告,因为您已传入两个数组。这就像尝试将两个地址分配给一个指针char *p = {a, b}。根据您的声明,有多个元素不必要。有关数组指针的真正含义,请参阅Geekforgeek's explanation

至于回答K& R练习,请考虑

选项1:

static char *daytab[2] = { 
    (char []) {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    (char []) {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };} 

或选项2:

static char (*daytab)[13] = (char [][13]) { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };} 

选项1是两个char指针的数组。

选项2是一个数组指针。它指向一个包含13个char元素的数组。正如您可以递增char指针以获取字符串中的下一个字母一样,您可以递增此数组指针以获取下一个13 char的数组。

答案 2 :(得分:0)

我自己在K&R中解决了这个问题,所以也许我可以补充已经给出的非常好的答案。这是一个很好的练习,可以避免使用二维数组,而可以使用指针数组。请注意,在本书的这一点上,我们还没有介绍import numpy as np from PIL import Image import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings def load_image_into_numpy_array(path): Load an image from file into a numpy array. Puts image into numpy array to feed into tensorflow graph. Note that by convention we put it into a numpy array with shape (height, width, channels), where channels=3 for RGB. Args: path: the file path to the image Returns: uint8 numpy array with shape (img_height, img_width, 3) return np.array(Image.open(path)) for image_path in IMAGE_PATHS: print('Running inference for {}... '.format(image_path), end='') image_np = load_image_into_numpy_array(image_path) # Things to try: # Flip horizontally # image_np = np.fliplr(image_np).copy() # Convert image to grayscale # image_np = np.tile( # np.mean(image_np, 2, keepdims=True), (1, 1, 3)).astype(np.uint8) # The input needs to be a tensor, convert it using `tf.convert_to_tensor`. input_tensor = tf.convert_to_tensor(image_np) # The model expects a batch of images, so add an axis with `tf.newaxis`. input_tensor = input_tensor[tf.newaxis, ...] # input_tensor = np.expand_dims(image_np, 0) detections = detect_fn(input_tensor) # All outputs are batches tensors. # Convert to numpy arrays, and take index [0] to remove the batch dimension. # We're only interested in the first num_detections. num_detections = int(detections.pop('num_detections')) detections = {key: value[0, :num_detections].numpy() for key, value in detections.items()} detections['num_detections'] = num_detections # detection_classes should be ints. detections['detection_classes'] = detections['detection_classes'].astype(np.int64) image_np_with_detections = image_np.copy() viz_utils.visualize_boxes_and_labels_on_image_array( image_np_with_detections, detections['detection_boxes'], detections['detection_classes'], detections['detection_scores'], category_index, use_normalized_coordinates=True, max_boxes_to_draw=200, min_score_thresh=.30, agnostic_mode=False) plt.figure() plt.imshow(image_np_with_detections) print('Done') plt.show() # sphinx_gallery_thumbnail_number = 2 。因此,一种方法是预先设置month数组,然后是指向这些数组的指针数组:

malloc

回想一下,数组的名称是指向第一个元素的指针。现在,您确实有一个指向两个由13个char y0[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char y1[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char *daytab[] = {y0, y1}; 组成的数组的指针的数组。