我正在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]) {...}
答案 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;
...然后互换使用ptr
和arr
。或者这个:
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};
组成的数组的指针的数组。