Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C_lect8.doc
Скачиваний:
2
Добавлен:
08.09.2019
Размер:
68.61 Кб
Скачать

2.2 Пример: Таблица химических элементов

Рассмотрим условия двух задач:

1. Написать программу, которая читает химическую формулу вещества и выдает молекулярную массу и элементный состав в процентах, например:

Na2SO4

Molecular mass: 142.037

Na: 32.37%

S: 22.57%

O: 45.06%

2. Написать программу, которая читает файл с данными о геометрической конфигурации молекулы (как в примере 1.3 из предыдущей лекции) и вычисляет координаты центра масс.

У этих двух задач (в общем-то совсем разных) есть общая особенность: нужно уметь находить атомную массу (а может быть и другие свойства), зная химический символ элемента. Очевидно, в программе нужно хранить таблицу свойств элементов и иметь функцию поиска информации в этой таблице. Посмотрим, как это можно было бы организовать.

typedef struct { /* Информация о химическом элементе: */

char sym[3]; /* символ химического элемента */

double mass; /* атомная масса в углеродных единицах */

} Element;

static Element table[] = {

{ "H" , 1.0079 },

{ "He", 4.0026 },

{ "Li", 6.941 },

{ "Be", 9.01218 },

{ "B" , 10.81 },

{ "C" , 12.011 },

{ "N" , 14.0067 },

. . . . . . . . . .

{ "Xe", 131.30 }

};

static int tbsz = sizeof(table) / sizeof(Element);

Для хранения свойств химического элемента используется структура, обозначаемая для удобства (с помощью typedef) как тип Element. Таблица свойств задана в виде массива table таких структур, причем ее содержимое определено с помощью инициализации (показана лишь часть таблицы). Обратите внимание на синтаксис: список инициализаторов элементов массива заключен в фигурные скобки, элементы разделяются запятыми. Поскольку каждый элемент массива является структурой, т.е. состоит из нескольких элементарных значений, то список этих значений в свою очередь заключается в фигурные скобки, а значения внутри скобок тоже разделяются запятыми.

Размер массива table явно не указан — в этом случае по правилам языка С число элементов массива будет равно количеству инициализаторов. Фактический размер таблицы хранится в переменной tbsz (название построено из слов “table size”), причем инициализирующее значение определяется как частное от деления размера всего массива на размер одного элемента (размер любого объекта в байтах дает операция sizeof). Такая организация облегчает в дальнейшем изменение таблицы: если захочется ее расширить, то нужно лишь добавить в список инициализаторов новые элементы и перекомпилировать программу. Фактический размер массива table и значение переменной tbsz автоматически согласованно изменятся.

Заметим, что таблица в таком виде больше подходит для первой задачи — хранится атомная масса природной смеси изотопов. Для второй задачи желательна более детальная информация — массы не атомов, а ядер, причем иногда могут понадобиться различные изотопы одного элемента. В этом случае структуру Element следует видоизменить, включив в нее дополнительные элементы данных, и соответствующим образом записать инициализаторы таблицы table.

Теперь рассмотрим функцию (назовем ее getinfo) поиска информации в таблице по заданному химическому символу sym. Она возвращает указатель на информацию об элементе (т.е. на элемент массива — структуру типа Element) либо NULL, если указанного символа в таблице нет.

#include <string.h>

/* Функция getinfo возвращает указатель на информацию об элементе

по его символу sym (или NULL, если символа нет в таблице) */

Element *getinfo (char *sym)

{

int i;

for (i = 0; i < tbsz; i++) {

if (strcmp(sym, table[i].sym) == 0) return table + i;

}

return NULL;

}

Здесь использована стандартная библиотечная функция сравнения двух строк strcmp(s1, s2), которая возвращает значение 0, если строки совпадают, и ненулевое значение, если строки различаются. Прототип этой функции содержится в стандартном заголовочном файле string.h. Результат поиска (указатель на найденный элемент) возвращается в виде выражения table+i, где i — индекс нужного элемента. Это выражение основано на связи между указателями и массивами и на правилах сложения указателей с целыми числами. То же самое выражение можно было бы записать и как &table[i] (т.е. указатель на i-й элемент массива table).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]