Хорошим местом для начала является JavaDocs . Они охватывают это:
Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
- Вызов метода экземпляра нулевого объекта.
- Доступ или изменение поля нулевого объекта.
- Выполнение длины null, как если бы это был массив.
- Доступ или изменение слотов с нулевым значением, как если бы это был массив.
- Бросать нуль, как если бы это было значение Throwable.
Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.
blockquote>Также, если вы попытаетесь использовать нулевую ссылку с
synchronized
, который также выдаст это исключение, за JLS :SynchronizedStatement: synchronized ( Expression ) Block
blockquote>
- В противном случае, если значение выражения равно null,
NullPointerException
.Как это исправить?
Итак, у вас есть
NullPointerException
. Как вы это исправите? Возьмем простой пример, который выдаетNullPointerException
:public class Printer { private String name; public void setName(String name) { this.name = name; } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer(); printer.print(); } }
Идентифицирует нулевые значения
. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:
Exception in thread "main" java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
Здесь мы видим, что исключение выбрано в строке 13 (в методе
printString
). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, чтоs
имеет значение null, а вызов методаlength
на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когдаs.length()
удаляется из метода.Трассировка, где эти значения взяты из
Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что
s
передается сprintString(name)
в методеprint()
, аthis.name
- null.Трассировка, где эти значения должны быть установлены
Где установлен
this.name
? В методеsetName(String)
. С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. Этого достаточно, чтобы дать нам решение: добавить вызов
printer.setName()
перед вызовомprinter.print()
.Другие исправления
Переменная может иметь значение по умолчанию (и
setName
может помешать ему установить значение null):private String name = "";
Либо метод
printString
может проверить значение null например:printString((name == null) ? "" : name);
Или вы можете создать класс, чтобы
name
всегда имел ненулевое значение :public class Printer { private final String name; public Printer(String name) { this.name = Objects.requireNonNull(name); } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer("123"); printer.print(); } }
См. также:
Я все еще не могу найти проблему
Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).
Вы можете использовать найденную функцию в этом вопросе , чтобы получить до 22 бит в C ++. Вот код из ссылки, соответствующим образом отредактированный:
template< unsigned long long N >
struct binary
{
enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
Итак, вы можете сделать что-то вроде binary<0101011011>::value
.
Как уже было сказано, стандарты C не имеют возможности напрямую писать двоичные числа. Однако есть расширения компилятора, и, судя по всему, C ++ 14 содержит префикс 0b
для двоичного кода. (Обратите внимание, что этот ответ был первоначально опубликован в 2010 году.)
Одним из распространенных способов решения является включение файла заголовка со вспомогательными макросами . Одним из простых вариантов является создание файла, который включает определения макросов для всех 8-битных шаблонов, например:
#define B00000000 0
#define B00000001 1
#define B00000010 2
…
. Это приводит только к 256 #define
s, а если больше 8-битного двоичного кода необходимы константы, эти определения могут быть объединены со сдвигами и OR, возможно с вспомогательными макросами (например, BIN16(B00000001,B00001010)
). (Имея индивидуальные макросы для каждого 16-битного, не говоря уже о 32-битном, значение не правдоподобно.)
Конечно, недостатком является то, что этот синтаксис требует записи всех ведущих нулей, но это также может сделать это более понятный для использования, как установка битовых флагов и содержимого аппаратных регистров. Для функционально-подобного макроса, приводящего к синтаксису без этого свойства, см. bithacks.h
, приведенную выше.
long long int
?
– wilhelmtell
10 April 2010 в 03:03
#define
, чем в заголовке BOOST_BINARY ...)
– Arkku
29 June 2012 в 16:15
Наименьшая единица, с которой вы можете работать, - это байт (который имеет тип char
). Вы можете работать с битами, хотя с помощью побитовых операторов.
Что касается целых литералов, вы можете работать только с десятичными (базовыми 10), восьмеричными (базовыми 8) или шестнадцатеричными (базовыми 16) числами. В C или C ++ нет бинарных (базовых 2) литералов.
Октальные числа имеют префикс 0
, а шестнадцатеричные числа имеют префикс 0x
. Десятичные числа не имеют префикса.
В C ++ 0x вы сможете делать то, что хотите, через пользовательские литералы .
<shameless_plug>
stackoverflow.com/questions/2611764#2611883 </shameless_plug>
– vladr
10 April 2010 в 03:05
0b00101010
в качестве удобства. SDCC - один, и я уверен, что есть и другие, которые тоже делают. (Править: Ха, избили меня, @ Джо!)
– Matt B.
10 April 2010 в 04:13
Слишком сложное мышление C ++ уже хорошо объяснено в других ответах здесь. Вот моя попытка сделать это с помощью C, keep-it-simple-ffs mindset:
unsigned char x = 0xF; // binary: 00001111
Вы можете использовать битсет
bitset<8> b(string("00010000"));
int i = (int)(bs.to_ulong());
cout<<i;
Этот поток может помочь.
/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)
/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))
#include <stdio.h>
int main(void)
{
// 261, evaluated at compile-time
unsigned const number = B16(00000001,00000101);
printf("%d \n", number);
return 0;
}
Он работает! (Все кредиты отправляются Тому Торфсу.)
##
соединяет маркеры вместе. Итак, в этом случае, если вы вызываете HEX__(10)
, он расширяется до 0x10LU
.
– James McNellis
10 April 2010 в 02:13
Вы можете попробовать:
bool i[8] = {0,0,1,1,0,1,0,1}
Я продлил хороший ответ, заданный @ renato-chandelier, обеспечив поддержку:
_NIBBLE_(…)
- 4 бит, 1 nibble в качестве аргумента _BYTE_(…)
- 8 бит, 2 глыбы в качестве аргументов _SLAB_(…)
- 12 бит, 3 глыбы в качестве аргументов _WORD_(…)
- 16 бит, 4 куска в качестве аргументов _QUINTIBBLE_(…)
- 20 бит, 5 глаголов в качестве аргументов _DSLAB_(…)
- 24 бит, 6 кусков в качестве аргументов _SEPTIBBLE_(…)
- 28 бит, 7 грызков в качестве аргументов _DWORD_(…)
- 32 бит, 8 глаголов в качестве аргументов На самом деле я не очень уверен в терминах «quintibble» и «septibble». Если кто-нибудь знает какую-либо альтернативу, пожалуйста, дайте мне знать.
Вот макрос, переписанный:
#define __CAT__(A, B) A##B
#define _CAT_(A, B) __CAT__(A, B)
#define __HEX_0000 0
#define __HEX_0001 1
#define __HEX_0010 2
#define __HEX_0011 3
#define __HEX_0100 4
#define __HEX_0101 5
#define __HEX_0110 6
#define __HEX_0111 7
#define __HEX_1000 8
#define __HEX_1001 9
#define __HEX_1010 a
#define __HEX_1011 b
#define __HEX_1100 c
#define __HEX_1101 d
#define __HEX_1110 e
#define __HEX_1111 f
#define _NIBBLE_(N1) _CAT_(0x, _CAT_(__HEX_, N1))
#define _BYTE_(N1, N2) _CAT_(_NIBBLE_(N1), _CAT_(__HEX_, N2))
#define _SLAB_(N1, N2, N3) _CAT_(_BYTE_(N1, N2), _CAT_(__HEX_, N3))
#define _WORD_(N1, N2, N3, N4) _CAT_(_SLAB_(N1, N2, N3), _CAT_(__HEX_, N4))
#define _QUINTIBBLE_(N1, N2, N3, N4, N5) _CAT_(_WORD_(N1, N2, N3, N4), _CAT_(__HEX_, N5))
#define _DSLAB_(N1, N2, N3, N4, N5, N6) _CAT_(_QUINTIBBLE_(N1, N2, N3, N4, N5), _CAT_(__HEX_, N6))
#define _SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7) _CAT_(_DSLAB_(N1, N2, N3, N4, N5, N6), _CAT_(__HEX_, N7))
#define _DWORD_(N1, N2, N3, N4, N5, N6, N7, N8) _CAT_(_SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7), _CAT_(__HEX_, N8))
И вот пример использования Ренато:
char b = _BYTE_(0100, 0001); /* equivalent to b = 65; or b = 'A'; or b = 0x41; */
unsigned int w = _WORD_(1101, 1111, 0100, 0011); /* equivalent to w = 57155; or w = 0xdf43; */
unsigned long int dw = _DWORD_(1101, 1111, 0100, 0011, 1111, 1101, 0010, 1000); /* Equivalent to dw = 3745774888; or dw = 0xdf43fd28; */
C не имеет записи native для чистых двоичных чисел. Ваша лучшая ставка здесь будет либо восьмеричной (например, 07777
) шестнадцатеричной (например, 0xfff
).
C ++ предоставляет стандартный шаблон с именем bitset
. Попробуйте, если хотите.
B_0100
не используется (вместо 0100
)? Как показано, например, char b = BYTE(0100,0001);
.
– Peter Mortensen
29 March 2017 в 16:09
Вы также можете использовать встроенную сборку следующим образом:
int i;
__asm {
mov eax, 00000000000000000000000000000000b
mov i, eax
}
std::cout << i;
Хорошо, это может быть несколько перебор, но работает:)
«Тип» двоичного числа совпадает с любым десятичным, шестнадцатеричным или восьмеричным числом: int
(или даже char, short, long long).
Когда вы назначаете константу, вы не можете назначить его 11011011 (любопытно и, к сожалению), но вы можете использовать hex. Hex немного легче мысленно перевести. Chunk in nibbles (4 бит) и перевести на символ в [0-9a-f].
На основании некоторых других ответов, но этот будет отклонять программы с незаконными бинарными литералами. Ведущие нули являются необязательными.
template<bool> struct BinaryLiteralDigit;
template<> struct BinaryLiteralDigit<true> {
static bool const value = true;
};
template<unsigned long long int OCT, unsigned long long int HEX>
struct BinaryLiteral {
enum {
value = (BinaryLiteralDigit<(OCT%8 < 2)>::value && BinaryLiteralDigit<(HEX >= 0)>::value
? (OCT%8) + (BinaryLiteral<OCT/8, 0>::value << 1)
: -1)
};
};
template<>
struct BinaryLiteral<0, 0> {
enum {
value = 0
};
};
#define BINARY_LITERAL(n) BinaryLiteral<0##n##LU, 0x##n##LU>::value
Пример:
#define B BINARY_LITERAL
#define COMPILE_ERRORS 0
int main (int argc, char ** argv) {
int _0s[] = { 0, B(0), B(00), B(000) };
int _1s[] = { 1, B(1), B(01), B(001) };
int _2s[] = { 2, B(10), B(010), B(0010) };
int _3s[] = { 3, B(11), B(011), B(0011) };
int _4s[] = { 4, B(100), B(0100), B(00100) };
int neg8s[] = { -8, -B(1000) };
#if COMPILE_ERRORS
int errors[] = { B(-1), B(2), B(9), B(1234567) };
#endif
return 0;
}
B(/2)
), либо разумно, но не двоично (например, B(+2)
), но также B(-001000000000000000000000)
(когда unsigned long long
равно 64 -бит), даже если все остальные отрицательные двоичные числа отклоняются. Кроме того, он равен B(001000000000000000000000)
, а не -B(001000000000000000000000)
, и могут быть определены большие двоичные числа, такие как -B(001111111111111111111111)
.
– jerry
20 May 2013 в 21:13
B(1+0)
. Я не уверен, как с этим бороться, и я не уверен, что C ++ справится с этим. В любом случае, я считаю, что сейчас нужно попытаться сделать что-то немое.
– Thomas Eding
20 May 2013 в 22:07
template<unsigned long N>
struct bin {
enum { value = (N%10)+2*bin<N/10>::value };
} ;
template<>
struct bin<0> {
enum { value = 0 };
} ;
// ...
std::cout << bin<1000>::value << '\n';
Самая левая цифра литерала все равно должна быть 1, но тем не менее.
binary<10>::value == binary<010>::value
и некоторая проверка ошибок)
– user
10 April 2010 в 03:30
int main() { cout << bitset<8>(42); }
– user 10 April 2010 в 03:40bitset
отзыв, я уже исправил бит оsetbase
, прежде чем увидел ваш комментарий. – vladr 10 April 2010 в 03:50