Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Следуя, что сказал Kyle, можно использовать макрос, чтобы сделать тяжелую работу для Вас.
Это возможно.
Для установки энного бита используйте ИЛИ:
x | = (1 <<5);//устанавливает 6-е - от права
Для очистки немного используйте И:
x& = ~ (1 <<5);//очищается 6-й от права
Для зеркального отражения немного используйте XOR:
x^ = (1 <<5);//6-е от права зеркальные отражения
Или...
#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set
#define SetBit(var, bit) (var |= (1 << bit))
#define FlipBit(var, bit) (var ^= (1 << bit))
Затем можно использовать его в коде как:
int myVar = 0;
SetBit(myVar, 5);
if (GetBit(myVar, 5))
{
// Do something
}
Это возможно.
Для установки энного бита используйте ИЛИ:
x |= (1 << 5); // sets the 5th-from right
Для очистки немного используйте И:
x &= ~(1 << 5); // clears 5th-from-right
Для зеркального отражения немного используйте XOR:
x ^= (1 << 5); // flips 5th-from-right
Для получения значения небольшого использования смещаются и И:
(x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right
примечание: право сдвига 5 состоит в том, чтобы гарантировать, что значение или 0 или 1. Если Вы просто интересуетесь 0/не 0, можно продвинуться без сдвига.
Теория
Нет никакого синтаксиса C для доступа или установки энного бита встроенного типа данных (например, 'символ'). Однако можно получить доступ к битам с помощью логической операции И и установить биты с помощью логического ИЛИ операции.
Как пример, скажите, что у Вас есть переменная, которая содержит 1101, и Вы хотите проверить 2-й бит слева. Просто выполните логическое И с 0100:
1101
0100
---- AND
0100
Если результат является ненулевым, то 2-й бит, должно быть, был установлен; иначе, не был установлен.
Если Вы хотите установить 3-й бит слева, затем выполнить логическое ИЛИ с 0010:
1101
0010
---- OR
1111
Можно использовать операторы C && (для И) и || (для ИЛИ) для выполнения этих задач. Необходимо будет создать разрядные схемы доступа (0100 и 0010 в вышеупомянутых примерах) сами. Прием должен помнить, что младший значащий бит (LSB) считает 1 с, следующий LSB считает 2 с, затем 4 с и т.д. Так, разрядная схема доступа для энного LSB (запускающийся в 0) является просто значением 2^n. Самый легкий способ вычислить это в C состоит в том, чтобы сместить двоичное значение 0001 (в этом примере на четыре бита) налево необходимым количеством мест. Поскольку это значение всегда равно 1 в подобных целому числу без знака количествах, это просто '1 <<n'
Пример
unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */
/* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */
unsigned char pattern = 1;
pattern <<= 3; /* Shift pattern left by three places.*/
if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */
/* Set the most significant bit. */
myVal |= (char)(1<<7);
Этот пример не был протестирован, но должен служить для иллюстрирования общего представления.
Запрашивать состояние бита с определенным индексом:
int index_state = variable & ( 1 << bit_index );
Установить бит:
varabile |= 1 << bit_index;
Перезапускать бит:
variable &= ~( 1 << bit_index );
Попытайтесь использовать битовые поля. Будьте осторожны, реализация может варьироваться компилятором.
http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html
ЕСЛИ Вы хотите индексировать немного, Вы могли:
bit = (char & 0xF0) >> 7;
получает msb символа. Вы могли даже не учесть сдвиг вправо и сделать тест на 0.
bit = char & 0xF0;
если бит будет установлен, то результат будет> 0;
obviousuly, необходимо изменить маску для получения различных битов (NB: 0xF является битовой маской, если это неясно). Возможно определить многочисленные маски, например.
#define BIT_0 0x1 // or 1 << 0
#define BIT_1 0x2 // or 1 << 1
#define BIT_2 0x4 // or 1 << 2
#define BIT_3 0x8 // or 1 << 3
и т.д...
Это дает Вам:
bit = char & BIT_1;
Можно использовать эти определения в вышеупомянутом коде для успешной индексации немного или в рамках макроса или в рамках функции.
Установить немного:
char |= BIT_2;
Очищаться немного:
char &= ~BIT_3
Переключить немного
char ^= BIT_4
Эта справка?
Отдельные биты могут быть индексированы следующим образом.
Определите структуру как этот:
struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned reserved : 28;
} bitPattern;
Теперь, если я хочу знать, что отдельные битовые значения var, названного "значением", делают следующее:
CopyMemory( &input, &value, sizeof(value) );
Чтобы видеть, является ли бит 2 высоким или низким:
int state = bitPattern.bit2;
Надеюсь, это поможет.
Существует стандартный контейнер библиотеки для битов: станд.:: вектор. Это специализировано на библиотеке, чтобы быть эффективным пространством. Существует также повышение dynamic_bitset класс.
Они позволят Вам выполнить операции на ряде булевых значений, с помощью одного бита за значение базовой системы хранения.
Повысьте динамическую bitset документацию
Для документации STL см. свою документацию компилятора.
Конечно, можно также обратиться к отдельным битам в других целочисленных типах вручную. Если Вы делаете это, необходимо использовать неподписанные типы так, чтобы Вы не получали неопределенное поведение, если решают сделать сдвиг вправо на значении с высоким набором битов. Однако это кажется на желание контейнеров.
Комментатору, который требовал, это берет 32x больше пространства, чем необходимый: повышение:: dynamic_bitset и вектор специализированы для использования одного бита за запись, и таким образом, нет штрафа пространства, предполагая фактическое желание больше, чем число битов в типе примитива. Эти классы позволяют Вам обращаться к отдельным битам в большом контейнере с эффективной базовой системой хранения. Если Вы просто хотите (говорят), что 32 бита, любой ценой, используют интервал. Если Вы хотите некоторое большое количество битов, можно использовать контейнер библиотеки.