Указатель по сравнению с массивом в C, нетривиальном различии

Я думал, что отвечу на свой вопрос, так как решил эту проблему для себя.

Нигде ни в одном из прочитанных мной документов или вопросов о переполнении стека я не заметил упоминаний о том, что обработка нескольких входящих вызовов возможна в браузере с помощью JavaScript SDK. Тем не менее, я смог это сделать. Кажется, что каждый Twilio.Device () может иметь несколько соединений. Таким образом, создав новый контейнер для телефона, как описано ниже, вы можете управлять каждым из них отдельно.

HTML

Connecting to Twilio...

Javascript

device.on('incoming', function(connection) {

    // get call sid
    var call_sid = connection.parameters.CallSid

    // get phone container which holds the buttons and call status etc.
    var phone_container = $('.phone_container')

    // if there is only one container and it's empty, use this to handle call
    if (phone_container.length == 1 && phone_container.attr('call_sid') == '') {
        // set call sid to container
        $('.phone_container').attr('call_sid', call_sid)
    }

    // else clone phone container for new call
    else {
        // clone , set call sid and append to main container
        $('.phone_container').first().clone().attr('call_sid', call_sid).appendTo($('#main_container'))
    }

});

Что касается передачи вызовов, я использовал конференц-залы для управления этим. Аналогично ответу Девина Рэйдера на этот вопрос: Twilio - Как перевести существующий вызов на конференцию

11
задан hlovdal 19 March 2009 в 01:23
поделиться

4 ответа

Массив является своего рода устройством хранения данных. Синтаксически, это используется в качестве указателя, но физически, нет никакой переменной "указателя" в той структуре — просто три ints. С другой стороны, международный указатель является фактическим типом данных, сохраненным в структуре. Поэтому при выполнении броска Вы, вероятно, * делающий ptr, берут значение первого элемента в массиве, а именно, 1.

*я не уверен, что это - на самом деле определенное поведение, но это - то, как оно будет работать над наиболее распространенными системами, по крайней мере.

10
ответ дан 3 December 2019 в 04:34
поделиться

Простите мне, если я пропускаю что-нибудь в Вашем анализе. Но я думаю фундаментальная ошибка во всем, что это неправильным предположением

type2_p-> ptr имеет тип "указатель на интервал", и значение является начальным адресом my_test.

Нет ничего, что заставляет его иметь то значение. Скорее это очень, вероятно, что это указывает где-нибудь на

0x00000001

Поскольку то, что Вы делаете, должно интерпретировать байты, составляющие тот целочисленный массив как указатель. Затем Вы добавляете что-то к нему и нижний индекс.

Кроме того, я высоко сомневаюсь, что Ваш кастинг к другой структуре на самом деле допустим (как в, гарантируемый работать). Можно бросить и затем считать общую начальную последовательность любой структуры, если они оба - члены объединения. Но они не находятся в Вашем примере. Также можно бросить к указателю на первого участника. Например:

typedef struct {
    int array[3];
} type1_t;

type1_t f = { { 1, 2, 3 } };

int main(void) {
    int (*arrayp)[3] = (int(*)[3])&f;
    (*arrayp)[0] = 3;
    assert(f.array[0] == 3);
    return 0;
}
11
ответ дан 3 December 2019 в 04:34
поделиться

Где мое обоснование неправильно/какой разве, я не понимаю?

type_1::array (не строго синтаксис C), не int *; это int [3].

Как я объявляю, что type2_t высказывает ptr мнение первому члену массива?

typedef struct 
{    
    int ptr[];
} type2_t;

Это объявляет участника массива с переменными границами. Из Стандарта C (6.7.2.1 абзаца 16):

Однако, когда a. (или->) оператор имеет левый операнд, который является (указатель на), структура с участником массива с переменными границами и правильным операндом называет того участника, это ведет себя, как будто тот участник был заменен самым долгим массивом (с тем же типом элемента), который не сделает структуру больше, чем объект получаемый доступ; смещение массива должно остаться смещением участника массива с переменными границами, даже если это отличалось бы от того из заменяющего массива.

Т.е. это может исказить type1_t::array правильно.

3
ответ дан 3 December 2019 в 04:34
поделиться

Должно быть определено поведение. Подумайте об этом с точки зрения памяти.

Для простоты предположим, что my_test находится по адресу 0x80000000.

type1_p == 0x80000000
&type1_p->my_array[0] == 0x80000000 // my_array[0] == 1
&type1_p->my_array[1] == 0x80000004 // my_array[1] == 2
&type1_p->my_array[2] == 0x80000008 // my_array[2] == 3

Когда вы приводите его к type2_t,

type2_p == 0x80000000
&type2_p->ptr == 0x8000000 // type2_p->ptr == 1
type2_p->ptr[0] == *(type2_p->ptr) == *1

Чтобы делать то, что вы хотите, вам придется либо создать вторичную структуру, либо назначьте адрес массива для ptr (например, type2_p-> ptr = type1_p-> my_array) или объявите ptr как массив (или массив переменной длины, например int ptr []).

В качестве альтернативы вы можете получить доступ к элементам некрасиво: (& type2_p-> ptr) [0] , (& type2_p-> ptr) [1] . Однако будьте осторожны, поскольку (& type2_p-> ptr) [0] на самом деле будет int * , а не int .

0
ответ дан 3 December 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: