Главная » iPhone, Objective-C, Программирование для iOS и MacOS » Строки С

0

Если у программиста Objective-C есть выбор, он всегда предпочтет работать с объектами NSString вместо строк С. Впрочем, иногда выбора нет. Самая распространенная причина для использования строк С? Работа с библиотеками С из кода Objective-C. Например, существует библиотека функций С, позволяющая вашей программе взаимодействовать с сервером баз данных PostgreSQL. Функции этой библиотеки используют строки С, а не экземпляры NSString.

char

В предыдущем разделе рассматривалась возможность интерпретации байтов как чисел. Байты также могут интерпретироваться как символы. Как упоминалось ранее, существует много разных кодировок символов. Самая старая, и пожалуй, самая известная – кодировка ASCII (American Standard Code for Information Interchange). В кодировке ASCII разные байты определяют разные символы. Например, код 0x4b соответствует символу «К». Создайте новую программу командной строки С с именем yostring.  Программа  будет  выводить  некоторые  символы  из  стандарта  ASCII.

Отредактируйте main.c:.

#include <stdio.h>

int main (int argc, const char * argv[])

{

char x = 0x21; // символ ‘!’ while (x <= 0x7e) { // символ ‘~’

printf("%x is %c\n", x, x); x++;

}

return 0; }

Возникает законный вопрос: «Байт может содержать одно из 256 чисел. Мы только что вывели 94 символа. А что происходит с остальными? Важно понимать, что кодировка ASCII разрабатывалась для управления старыми терминалами, работавшими по принципу телетайпа, которые печатали данные на бумаге (вместо вывода на экран). Например, при выводе числа 7 в кодировке ASCII устройство издает звуковой сигнал. Символы 0-31 в ASCII соответствуют непечатаемым управляющим символам: 32 – символ пробела, 127 – удаление предыдущего символа и т. д. Как насчет символов 128-255?  В ASCII  используются  только 7  битов,  для кода  128 ASCII – символа не существует.

Коды ASCII могут использоваться в коде как литералы, достаточно заключить их в апострофы. Внесите изменения в свой код:

int main (int argc, const char * argv[])

{

char x = ‘!’; // The character ‘!’

while (x <= ‘~’) { // The character ‘~’ printf("%x is %c\n", x, x); x++;

}

return 0; }

Постройте и запустите программу

Непечатаемые символы могут быть представлены в виде управляющих последовательностей, начинающихся с символа \. Запись \n уже использовалась для символа новой строки. Приведу несколько распространенных последовательностей:

Таблица 34.1. Часто используемые управляющие последовательности

\n                                            новая строка

\t                                             табуляция

\’                                              апостроф

\"                                             кавычка

\0                                            нуль-байт (0x00)

\\                                             обратная косая черта

Char *

Строка С представляет собой простой набор символов, расположенных в смежной области памяти. Конец строки обозначается символом 0x00.

Рис. 34.1. Строка С со словом «Love»

Функции, которым передаются строки С, рассчитывают получить адрес первого символа строки. Например, функция strlen() считает количество символов в строке. Попробуйте создать строку и использовать strlen() для подсчета символов:

#include <stdio.h> // For printf

#include <stdlib.h> // For malloc/free

#include <string.h> // For strlen

int main (int argc, const char * argv[])

{

char x = ‘!'; // The character ‘!’ while (x <= ‘~’) { // The character ‘~’

printf("%x is %c\n", x, x); x++;

}

// получение указателя на 5 байтпамяти в куче char *start = malloc(5);

// в первый байт записывается ‘L’

*start = ‘L';

// во второй байт записывается ‘o’

*(start + 1) = ‘o';

// в третий байт аписывается ‘v’

*(start + 2) = ‘v';

// в четвертый байт записывается ‘e’

*(start + 3) = ‘e';

// в пятый байт записывается нуль

*(start + 4) = ‘\0′;

// вывод строки и ее длины

printf("%s has %zu characters\n", start, strlen(start));

// вывод третьей буквы

printf("The third letter is %c\n", *(start + 2));

// освобождение памяти для повторного использования free(start);

start = NULL;

return 0;

}

Постройте и запустите про грамму.

Обратите внимание на места с суммированием указателя и числа. Переменная start объявляется с типом char *. Тип char занимает один байт. Следовательно, значение start+1 представляет собой указатель, смещенный на 1 байт в памяти по отношению к start; start+2 – на 2 байта и т. д.

Рис. 34.2. Адреса символов строки

Прибавление к указателю и разыменование результата – операция настолько распространенная,  что  для  нее  было  создано  специальное  сокращение:  запись

start[2] эквивалентна *(start+ 2). Внесите изменения в свой код:

char *start = malloc(5);

start[0] = ‘L';

start[1] = ‘o';

start[2] = ‘v';

start[3] = ‘e';

start[4] = ‘\0′;

printf("%s has %zu characters\n", start, strlen(start)); printf("The third letter is %c\n", start[2]);

free(start); start = NULL;

return 0; }

Постройте и запустите программу.

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

int main (int argc, const char * argv[])

{

// выделение блока памяти, размеров которого достаточен

// для хранения трех значений типа float float *favorites = malloc(3 * sizeof(float));

//занесение значений в ячейки буфера favorites[0] = 3.14158;

favorites[1] = 2.71828;

favorites[2] = 1.41421;

// вывод всех чисел в списке for (int i = 0; i < 3; i++) {

printf("%.4f is favorite %d\n", favorites[i], i);

}

// освобождение памяти для повторного использования free(favorites);

favorites = NULL; return 0; }

Единственное интересное различие заключается в том, что переменная favorites объявлена с типом float *. Тип float занимает 4 байта. Следовательно, результат favorites+1 смещен на 4 байта в памяти по отношению к favorites.

Источник: Аарон Хилегас, «Objective-C. Программирование для iOS и MacOS», 2012 г.

По теме:

  • Комментарии