C Добавление значения в массив?`массив + значение` - PullRequest
0 голосов
/ 25 декабря 2018

Я просматривал какой-то код и наткнулся на эту строку кода.(С другими строками кода для обеспечения контекста)

void write32le(int in, unsigned char * buf) {
    buf[0]=in&0xff;
    buf[1]=(in>>8)&0xff;
    buf[2]=(in>>16)&0xff;
    buf[3]=(in>>24)&0xff;
}

.......

unsigned char wavhead[44] = {
    0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,  0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
    0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61,  0x00, 0x00, 0x00, 0x00
    };

.......

write32le(outsizetotal,wavhead+4);

Последние две строки кода находятся в одной и той же функции, если это имеет значение, и вопрос, который у меня есть, находится в последней строке."wavhead + 4", что именно он делает?Присоединение числа 4 к 'wavhead'?

Ответы [ 5 ]

0 голосов
/ 25 декабря 2018

в этом случае имя массива wavhead [] равно указателю «unsigned char *», добавление 4 к этому указателю просто перемещает указатель на 4 шага, а шаг - sizeof (unsigned char),который равен 1. Итак, wavhead + 4 = адрес указателя wavhead + 4, и он указывает на wavhead [4] после добавления.

0 голосов
/ 25 декабря 2018

В большинстве контекстов (с несколькими исключениями) объект типа «массив» неявно преобразуется в значение типа «указатель».Указатель указывает на первый элемент массива.Например, в таких контекстах обычный wavhead неявно интерпретируется как &wavhead[0].

В вашем случае wavhead используется в качестве операнда бинарного оператора +.Двоичный код + не является исключением.Итак, wavhead затухает до &wavhead[0], и ваш вызов интерпретируется как

write32le(outsizetotal, &wavhead[0] + 4);

, что означает, что у вас действительно есть «указатель + значение», а не «массив + значение».

Второй аргумент приводит к указателю на wavhead[4].Вы также можете переписать его как

write32le(outsizetotal, &wavhead[4]);
0 голосов
/ 25 декабря 2018

Массивы - это непрерывный блок памяти, доступ к которому осуществляется по адресу (местоположение элемента 0) и смещению.

wavehead+4 вычисляет адрес 5-го элемента в массиве.Метод, в который он передан (write32le), увидит 5-й элемент массива как 1-й элемент.

// If we take an array
int myArr[] = { 1, 2, 3, 4, 5, 6 }
// And pass it into a method as
myMethod(myArr+2);
// the method will see (assuming it knows the length of the array which it won't in c)
{ 3, 4, 5, 6 }
0 голосов
/ 25 декабря 2018

Цель write32le() состоит в том, чтобы взять слово, которое вы хотите переписать в качестве первого аргумента, и индекс в массиве unsigned int в виде указателя.wavhead[index] это указатель такого типа.

Если вы хотите заменить первые 4 байта wavhead словом 0xDEADBEEF, вы должны сделать это:

int main()
{
    int in=0xDEADBEEF;
    printf("Before write32le:\n ");
    for(int i=0; i<=3; i++)
    {
        printf("0x%hhx ", wavhead[i]);
    }
    printf("\n");

    write32le(in, wavhead);
    printf("After write32le:\n ");
    for(int i=0; i<=3; i++)
    {
        printf("0x%hhx ", wavhead[i]);
    }
    printf("\n");

    return 0;
}

Вывод:

Before write32le:
 0x52 0x49 0x46 0x46
After write32le:
 0xef 0xbe 0xad 0xde
0 голосов
/ 25 декабря 2018

Нет, он передает адрес (указатель) на 5-й элемент массива (который имеет индекс 4, так как индексы начинаются с нуля).

Вам нужно выучить указатели и массивы.В C вы не можете добавлять или удалять элементы из массива

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