Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Уч. пос. МПТ (2.04.12).pdf
Скачиваний:
403
Добавлен:
22.03.2015
Размер:
10.95 Mб
Скачать

2.2.19 Функция создания форматированных строк SNPRINTF

Функция snprintf входит в библиотеку STDIO.h, которая подключается директивой

#include <STDIO.h>

Основное назначение функции — перевод двоичной числовой информации в десятичную (или другую) систему счисления, представление в формате, удобном для восприятия человеком.

snprintf(S,L,"Формат",N1,N2,...);

Здесь S — переменная строкового типа (массив char), в которую сохраняется результат; L — целочисленная константа, на единицу превышающая число символов в строке S; «Формат» — строка, определяющая форматирование (см. ниже), N1, N2 и т. д. — числовые переменные или константы.

Строка формата — это произвольный текст, в который внедрены специальные символы форматирования. Функция snprintf повторит этот текст в переменной S, а в место символов форматирования подставит числа N1, N2 по порядку. Числа будут соответствующим образом отформатированы.

Каждое обозначение формата начинается с символа «%», за которым следуют несколько необязательных символов и один обязательный указатель типа (рисунок 2.2.1).

 

 

Необязательные

 

 

%

F

W

. P

L

T

 

Флаги:

Длина

Точность

Модиф.

Тип:

 

–, + , #,

(число)

(число)

длины:

d, u, o,

 

пробел

 

 

h, hh

x, X, f, e

Рисунок 2.2.1 – Строка формата

В таблицах 2.2.3–2.2.4 приведены возможные значения полей «Тип», «Флаги» и «Модификатор длины». Флагов может быть указано сразу несколько подряд.

Поле «Длина» (W) определяет число позиций, отводимых для представления форматированного числа. Если число короче, оно дополняется пробелами слева или справа в зависимости от флага «–». Если число длиннее, то формат будет нарушен и длина строки увеличена.

Поле «Точность» (P), отделяемое от поля «Длина» точкой для дробных типов (f/F, e/E) устанавливает число точек после запятой для дробной части числа (мантиссы). Если точность не указана, подразумевается 6 знаков после запятой. Для целых чисел определяет число позиций, которое достигается добавлением слева незначащих нулей.

Символ «x» или «X» определяет, малые или прописные буквы используются для обозначения шестнадцатеричных цифр («a»–«f» или «A»–«F»).

Малая или приписная буква f/F или e/E в поле формата определяет, малые или прописные буквы (e/E) используются для отделения мантиссы от порядка, а также обозначения бесконечности (inf/INF) и неопределенности

(nan/NAN).

116

Таблица 2.2.3 – Возможные значения поля «Тип»

Тип

Пояснения

d

Десятичное целое со знаком

u

Десятичное целое без знака

o

Восьмеричное целое

x, X

Шестнадцатеричное целое

f, F

Дробный формат

e, E

Экспоненциальный формат

Таблица 2.2.4 – Возможные значения поля «Флаг»

Флаг

Пояснения

 

Выравнивание по левому краю. Если длина строки (W) превышает

фактическое число символов, строка дополняется нулями справа. По

 

умолчанию — слева (выравнивание по правому краю).

+

Отображать знак «+» для положительных чисел

#

Обозначать восьмеричные числа нулем слева, а шестнадцатеричные

символами «0x» или «0X» в зависимости от формата «x» или «X»

 

пробел

Дополнять слева пробелом положительные числа, резервируя пози-

цию под знак «–»

Таблица 2.2.5 – Примеры применения функции snprintf для форматирования

Числовая переменная

Формат

Результат

int N=123;

snprintf(S,11,"%d V",N)

–123˽V˽˽˽˽

int N=–123;

snprintf(S,11,"%8d V",N)

˽˽˽˽–123˽V

 

snprintf(S,11,"%-8d V",N)

123˽˽˽˽˽˽V

int N=123;

snprintf(S,11,"%8.8d V",N)

00000123˽V

 

snprintf(S,11,"% 8d V",N)

˽˽˽˽˽123˽V

int N=–123;

snprintf(S,11,"% 8d V",N)

˽˽˽˽–123˽V

snprintf(S,11,"%8.5d V",N)

˽˽–00123˽V

 

int N=123;

snprintf(S,11,"%+8d V",N)

˽˽˽˽+123˽V

snprintf(S,11,"%o",N)

710˽˽˽˽˽˽˽

 

 

snprintf(S,11,"%u",N)

4294968173

 

snprintf(S,11,"%x",N)

ffffff85˽˽

int N=–123;

snprintf(S,11,"%X",N)

FFFFFF85˽˽

snprintf(S,11,"%#x",N)

0xffffff85

 

 

snprintf(S,11,"%hX",N)

FF85˽˽˽˽˽˽

 

snprintf(S,11,"%hhX",N)

85˽˽˽˽˽˽˽˽

 

snprintf(S,11,"%f",N)

3.141593˽˽

 

snprintf(S,11,"%8.4f",N)

˽˽3.1416˽˽

 

snprintf(S,11,"%.2рад",N)

3.14рад˽˽˽

float N=3.1415927;

snprintf(S,11,"%-7.2fрад",N)

3.14˽˽˽рад

 

snprintf(S,11,"%+-7.2fрад",N)

+3.14˽˽рад

 

snprintf(S,11,"%5.3e",N)

3.142e+00˽

 

snprintf(S,11,"%5.3E",N)

3.142E+00˽

117

Модификатор длины «h» заставляет считать число двухбайтным, а «hh» — однобайтным независимо от истинного размера переменной.

Обращаем внимание на то, что функция snprintf не поддерживает тип long long.

Таблица 2.2.5 содержит множество полезных примеров формирования строки S из 10 символов, объявленной как char S[11].

2.2.20 Ассемблер в Си-программах

Раздел 2.6 посвящен составлению программы на ассемблере без участия Си-компилятора. Здесь речь пойдет о внедрении кода на ассемблере в Си-программу.

Как известно, код, генерируемый Си-компилятором, в некоторой степени избыточен. Поэтому он неоптимален с точки зрения быстродействия и (или) объема. С целью оптимизации в Си-программы внедряют фрагменты, составленные на ассемблере. Компилятор RealView 4 поддерживает два способа, так называемые, «внедряемый ассемблер» (Embedded Assembler) и «встраиваемый ассемблер» (Inline Assembler).

Блок внедряемого ассемблера имеет формат

asm

{

... ;

// Инструкции ассемблера

}

Использование внедряемого ассемблера ограничено несколькими обстоятельствами:

а) вместо регистров используются «виртуальные регистры», то есть компилятор вправе размещать данные, обозначенные как R0–R12 в произвольных регистрах общего назначения;

б) доступ к регистрам R13–R15 невозможен;

в) если оптимизация кода в настройках компилятора включена, то она будет применена и к коду внедряемого ассемблера; так что точное совпадение инструкций и исполнимого кода не гарантируется;

Фрагмент встраиваемого ассемблера всегда оформляется как функция:

asm void Имя_функции(Параметры)

{

... ;

// Инструкции ассемблера

}

Ограничения, перечисленные выше для внедряемого ассемблера, здесь не действуют. Отметим, что практически код повторяется в точности. Так что даже команда возврата из подпрограммы (bx LR) автоматически не будет сгенерирована компилятором.

Пример использования встраиваемого ассемблера для формирования временной задержки рассмотрен в практическом занятии №2 (раздел 3.2.6).

118