Пусть массив указывает на другой массив с разными границами в C ++ - PullRequest
0 голосов
/ 01 марта 2019

Мне нужно использовать библиотеку, которая имеет следующий typedef и метод:

typedef short int SomeArray[3];

void method(SomeArray* arr){//doSomething}

В моем основном коде у меня большой массив и я хочу меньший массив, который имеет точно такие же значения индекса, как и больший массив:

short int var[5] = {0, 1, 2, 4, 5};

Мне нужна переменная типа SomeArray, чья [0] = var [1], [1] = var [2], [2] = var [3], чтобы передать ее вМетод испытания.Это:

short int* intf = &var[1];

дает то, что мне нужно, когда я получаю к нему доступ через intf [?].Но как преобразовать его в переменную типа SomeArray в массив из 3 элементов?Я пробовал разные методы, такие как

SomeArray* arr = intf;
SomeArray* arr = (SomeArray*)intf;
SomeArray* arr = &var[1];

Но либо он не работает, либо адрес элемента каждого элемента arr не совпадает с адресом элемента (на необходимой позиции) большего массива.

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Вы, вероятно, можете прекратить преобразование адреса var[1] в тип указателя на массив из трех элементов.Это, вероятно, незаконно, строго говоря, потому что я предполагаю, что это нарушает строгие правила псевдонимов (к типизированным объектам можно обращаться только через выражения совместимых типов) - но только очень немного; -) 1 .С семантической точки зрения проблем нет, потому что все шорты ожидаются в массиве из 3 элементов.Это, вероятно, будет работать везде, строго говоря:

$ g++ --version && cat arrpassing.cpp && g++ -Wall -o arrpassing -O3 arrpassing.cpp && ./arrpassing
g++ (GCC) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


#include<iostream>
using namespace std;

typedef short int SomeArray[3];

void method(SomeArray* arr)
{
  int i=0;
  for(auto el: *arr) cout << "arr[" << i++ << "]: " << el << '\n';
}

int main()
{
  short arr5[5] = { 0,1,2,3,4 };

  method((SomeArray *)(arr5+1));

  return 0;
}

arr[0]: 1
arr[1]: 2
arr[2]: 3


1 Это действительно пограничный вопрос.Очевидно, что вы можете получить доступ к отдельным элементам массива с помощью простых указателей для ввода;и стандарт C ++ рассматривает отдельные объекты как массивы размера 1 в определенных ситуациях, так что вы могли бы доказать, что можно обращаться к памяти больших массивов через «подмассивы» (разумеется, того же типа элемента).
0 голосов
/ 01 марта 2019

Мне нужна переменная типа SomeArray, чья [0] = var [1], [1] = var [2], [2] = var [3], чтобы передать ее в метод test ()

Но как преобразовать [больший массив] в переменную типа SomeArray в массив из 3 элементов?

Примерно так:

short big_array[] {0, 1, 2, 4, 5};
SomeArray small_array {
    big_array[1],
    big_array[2],
    big_array[3],
};
method(&small_array);

Однако, если вам всегда нужен подмассив (т.е. всегда нужны последовательные элементы), вы можете избежать копирования, изменив method, чтобы просто взять указатель на первый элемент массива:

void method2(short arr[3]);

Таким образом, вы можете вызывать функцию с подмассивом массива любого размера (при условии, что в нем достаточно элементов):

short big_array[] {0, 1, 2, 4, 5};
method2(big_array + 1);

С другой стороны, проверка типов во время компиляции не спасет нас от ошибоки передача слишком маленького массива просто имеет неопределенное поведение.


Эта идея может быть расширена, и вы можете поддерживать любую другую (обходную) структуру данных в дополнение к массивам, сделав method шаблоном функции.и принять любой произвольный итератор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...