Стандарт С не допускает этого.
6.5.6 Аддитивные операторы (выделение мое)
8 Когда выражение, имеющее целочисленный тип, добавляется или вычитается из указателя, результат имеет тип операнда указателя. Если операнд-указатель указывает на элемент объекта массива , и массив достаточно велик, результат указывает на смещение элемента от исходного элемента, так что различие индексов полученного и исходного массива элементы равны целочисленному выражению. Другими словами, если выражение P указывает на i-й элемент объекта массива, выражения (P) + N (эквивалентно, N + (P)) и (P) -N (где N имеет значение n) указывают соответственно i + n-му и in-му элементам массива, если они существуют. Кроме того, если выражение P указывает на последний элемент объекта массива, выражение (P) +1 указывает один за последним элементом объекта массива, а если выражение Q указывает на один последний элемент последнего элемента массива, выражение (Q) -1 указывает на последний элемент объекта массива. Если и операнд-указатель, и результат указывают на элементы одного и того же объекта массива или один после последнего элемента объекта массива, при оценке не должно быть переполнения; в противном случае поведение не определено . Если результат указывает на один последний элемент массива, он не должен использоваться в качестве операнда оцениваемого унарного оператора *.
blockquote>Для целей вышеизложенного указатель на отдельный объект рассматривается как указывающий на массив из 1 элемента.
Теперь
((uint8_t*)0)
не указывает на элемент объекта массива. Просто потому, что указатель, содержащий нулевое значение указателя, не указывает на какой-либо объект . Сказано в:6.3.2.3 Указатели
3 Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем, гарантированно сравнивается с указателем на любой объект или функцию.
blockquote>Так что вы не можете делать арифметику с ним. Предупреждение оправдано, потому что, как упоминается во втором выделенном предложении, мы имеем дело с неопределенным поведением.
Не обманывайтесь тем фактом, что макрос
offsetof
возможно реализован подобным образом. Стандартная библиотека не связана с ограничениями, накладываемыми на пользовательские программы. Это может использовать более глубокие знания. Но делать это в нашем коде не очень хорошо определено.
Для размера дисплея Вы захотите Screen
.PrimaryScreen.Bounds.Size
(или Screen.GetBounds(myform)
).
Если Вы хотите DPI, используйте свойства DpiX и DpiY Графики:
PointF dpi = PointF.Empty;
using(Graphics g = this.CreateGraphics()){
dpi.X = g.DpiX;
dpi.Y = g.DpiY;
}
О, ожидайте! Вы хотели фактический, держите линейку до монитора и меры, размера?! Нет. Не возможное использование любых служб ОС. ОС не знает фактических размеров монитора, или как пользователю калибровали его. Часть этой информации теоретически обнаруживаема, но это не достаточно детерминировано, чтобы ОС использовала его надежно, таким образом, это не делает.
Как работа вокруг, можно попробовать несколько вещей.
После того как Вы знаете (или думайте, что Вы знаете), диагональный размер монитора, необходимо найти его физическое соотношение сторон. Снова, несколько вещей:
После того как Вы знаете (или думайте, что Вы знаете), каковы диагональный размер монитора и физическое соотношение сторон, затем Вы можно вычислить, это - физическая ширина и высота. A2 + B2 = C2, таким образом, несколько вычислений дадут его Вам хороший:
Если Вы узнали, что это - 17-дюймовый монитор, и его текущее разрешение составляет 1280 x 1024:
12802 + 10242 = 2686976
Sqrt (2686976) = 1639.1998047828092637409837247032
17 дюймов * 1280 / 1639.2 = 13,274768179599804782820888238165 дюймов
17 дюймов * 1024 / 1639.2 = 10,619814543679843826256710590532 дюймов
Это помещает физическую ширину в 13,27 дюймов и физическую высоту на уровне 10,62 дюймов. Это делает пиксели 13,27 дюймами / 1280 = 10,62 дюймов / 1024 = 0,01037 дюйма или приблизительно 0,263 мм.
Конечно, все это недопустимо, если у пользователя нет подходящего разрешения, монитор имеет дурацкие неквадратные пиксели, или это - более старый аналоговый монитор, и средства управления не корректируются правильно для дисплея для заполнения всего физического экрана. Или хуже, это мог быть проектор.
В конце можно быть лучшими от выполнения калибровочного шага, где у Вас есть пользователь, на самом деле содержат линейку до экрана и измеряют размер чего-то для Вас. Вы могли:
Независимо от того, что Вы делаете, не ожидайте, что Ваши результаты будут на 100% точны. Существует слишком много факторов в действии для Вас (или пользователь) для получения, это точно исправляет, каждый раз.
Знайте, что 96 точек на дюйм обычно достаточно близки к точному. Современные пиксели на неспроектированных экранах, все склонны быть приблизительно 0,25 мм, плюс-минус, таким образом, Вы обычно заканчиваете приблизительно с 100 физическими пикселями на дюйм, плюс-минус, если монитор установлен на свое родное разрешение. (Конечно, это - огромное обобщение и не относится ко всем мониторам. ПК Eee, например, имеют пиксели приблизительно 0,19 мм в размере, если я помню спецификации правильно.)
извините, Вы имеете к P/Invoke для этой информации.
Вот ссылка, которую я использовал для него только что: http://www.davidthielen.info/programming/2007/05/get_screen_dpi_.html
GetDeviceCaps
может быть P/Invoke'd для получения некоторых чисел, но я никогда не знал, что числа что защищены...
Можно проверить просто вручную вычисление от размера экрана
cos(45)*LCD_SCREEN_DIAGONAL_IN_INCHES/sqrt(HORZ_RES^2 + VERT_RES^2)
Это дало бы Вам пиксельную ширину в дюймах