Только одна строка! path
и line
являются строками
import java.nio.file.Files;
import java.nio.file.Paths;
Files.write(Paths.get(path), lines.getBytes());
Подумайте, что такое указатель ... это адрес памяти. Каждый байт в памяти имеет адрес. Итак, если у вас есть int
, то есть 4 байта, а его адрес равен 1000, 1001 фактически является вторым байтом этого int
, а 1002 - третьим байтом, а 1003 - четвертым. Поскольку размер int
может отличаться от компилятора к компилятору, крайне важно, чтобы при инкрементах указателя вы не получили адрес некоторой средней точки в int
. Таким образом, задача определения количества пропущенных байтов, основанных на вашем типе данных, обрабатывается для вас, и вы можете просто использовать любое значение, которое вы получаете, и не беспокоиться об этом.
Как указывает Базиле Старинквич , эта сумма будет варьироваться в зависимости от свойства sizeof
указанного элемента данных. Очень легко забыть, что хотя адреса последовательны, указатели на ваши объекты должны учитывать фактическое пространство памяти, необходимое для размещения этих объектов.
Вам действительно нужно потратить время, чтобы прочитать хорошую книгу языка программирования C (например, K & amp; R "язык программирования C" )
Арифметика указателя - сложный вопрос. Добавление указателя означает переход к следующему остроконечному элементу. Таким образом, адрес увеличивается на sizeof
заостренный элемент.
Указатель используется для указания на определенный байт маркировки памяти, где объект был выделен (технически он может указывать в любом месте, но именно так он используется). Когда вы выполняете арифметику указателей, она работает в зависимости от размера объектов, на которые указывает. В вашем случае это указатель на целые числа, размер которых равен 4 байтам.
Рассмотрим указатель p
. Выражение p+n
похоже на (unsigned char *)p + n * sizeof *p
(потому что sizeof(unsigned char) == 1
). Попробуйте следующее:
#include <stdio.h>
#define N 3
int
main(void)
{
int i;
int *p = &i;
printf("%p\n", (void *)p);
printf("%p\n", (void *)(p + N));
printf("%p\n", (void *)((unsigned char *)p + N * sizeof *p));
return 0;
}
Короткий ответ
Адрес указателя будет увеличен на sizeof(T)
, где T
- тип, на который указывает. Таким образом, для int
указатель будет увеличен на sizeof(int)
.
Почему?
Ну, в первую очередь, стандарт требует этого. Причина, по которой это поведение полезна (кроме совместимости с C), заключается в том, что, когда у вас есть структура данных, которая использует непрерывную память, например массив или std::vector
, вы можете перейти к следующему элементу массива, просто добавив один к указателю. Если вы хотите перейти к n-му элементу в контейнере, вы просто добавите n.
Возможность писать firstAddress + 2
намного проще, чем firstAddress + (sizeof(T) * 2)
, и помогает предотвратить ошибки, возникающие у разработчиков, предполагающих sizeof(int)
4 (это может быть не так) и писать код, как firstAddress + (4 * 2)
.
На самом деле, когда вы говорите myArray[4]
, вы говорите myArray + 4
. Это причина, по которой индексы массивов начинаются с 0; вы просто добавляете 0, чтобы получить первый элемент (т. е. myArray указывает на первый элемент массива) и n, чтобы получить n-й.
Что делать, если я хочу переместить один байт за раз?
sizeof(char)
гарантированно будет иметь один байт, поэтому вы можете использовать char*
, если хотите переместить один байт за раз.
Поскольку указатели предназначены для совместимости с массивами:
*(pointer + offset)
эквивалентно
pointer[offset]
Таким образом, арифметика указателя не работает в терминах байтов, но в терминов блоков sizeof(pointer base type)
-bytes.