Чем char отличается от string
Перейти к содержимому

Чем char отличается от string

  • автор:

Типы данных char и String: примеры применения — введение в Java 004 #

Таблица символов

Если в программе нужны символы, то для этого мы пользуемся типом данных char. Например:

public class HelloChar   public static void main(String[] args)    char zahl = 100;  // Сотый по счёту символ в таблице  char octal = '\u039A';  // Вызов определённого символа кодом  char zeichen = 'A';  // Буква A  char tabulator = '\t'; // В русском языке клавиша называется "Таб"  // Табулятор  char phi = '\u03A6';  // Греческая буквая Фита - PHI   System.out.println(zahl);  System.out.println(octal);  System.out.println(zeichen);  System.out.print(tabulator);  System.out.println(phi);  > > 

Объект базового (примитивного) типа char является 16-битным символом Unicode.

Мы можем вывести любое сообщение или любой символ. однако достаточно сложно вывести на экран кавычки, ведь в них мы и держим значения наших переменных. Для таких случаев мы используем экранирование. С помощью обратной косой черты(обратный слеш) мы экранируем символ или используем её для дополнительных параметров.

\b Backspace (Курсор двигается на одно место влево) \n Newline (Новая строчка) \f Newpage (Новая страница) \r Carriage return (Курсор становится на первое место в строчке, возврат каретки) \t Горизонтальный табулятор \" Двойная кавычка \' Одинарная кавычка \\ Backslash(вызов обратного слэша) \___ Символы с октальным значением от 000 до 377, например \304 соответствует символу Ä \u___ Вызов символа уникода (Unicode-16). Где например \u00C4 соответствует Ä 

Таблица символов Windows (charmap) вызывает и показывает именно те символы, которые можно вызвать в Java.

String #

Мы можем хранить в программе и набор символов: пароль, фамилию, звание, название улицы или просто набор символов. Для хранения таких данных можно использовать String. Пример использования:

public class HelloString   public static void main(String[] args)   String firstname = "Andrej";  String secondname = "Podlubnyj";  char copyright = '\u00A9';  int old = 18;  System.out.println(firstname + " " + secondname + " " + old);  String student = firstname + " " + secondname + " " + copyright;  System.out.println(student);  > > 

Один символ можно записать как “маленьким” стрингом, так и через символ при помощи типа данных char. Цепочку символов, больше одного, мы храним в типе данных String. Каждый элемент этой цепочки символов можно отобразить при помощи char. Это очень важно понять и запомнить.

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

 int dlina; dlina = student.length(); System.out.println(dlina); 

Для переменных типа String ява заготовила много дополнительных методов, которые делают нашу жизнь проще. Например, метод substring, который вырезает из одной цепочки символов другую.

public class WhatCanYouDoString   public static void main(String[] args)   String name = "AndrejPodlubnyj";  int dlina = name.length();  System.out.println(name);  System.out.println(dlina);   // вырезать символы с 6-го по 15-ый  String firstName = name.substring(6,15);   dlina = firstName.length();  System.out.println(firstName);  System.out.println(dlina);  > > 

Если мы пишем приложение для веб-сайта с “user generated content”, то мы можем столкнуться с тем, что часть контента пишется заглавными буквами. В Java есть методы, которые приводят цепочку символов алфавита к прописным (заглавным) или к строчным (маленьким) буквам. Давайте рассмотрим пример:

public class UppercaseAndLowercase   public static void main(String[] args)   String articleTitle = "london is the capital";  articleTitle = articleTitle.substring(0,1).toUpperCase() + articleTitle.substring(1);  System.out.println(articleTitle);   articleTitle = articleTitle.toUpperCase();  System.out.println(articleTitle);   System.out.println(articleTitle.toLowerCase());  > > 

С помощью метода toUpperCase() мы делаем буквы прописными, с помощью метода toLowerCase() мы приводим значение строки к строчным буквам.

Мы обязательно вернёмся к этому и другим возможностям класса. Пока надо только запомнить, что, если мы хотим создать записную книжку, то фамилию и имя абонента мы скорее всего будем хранить с помощью типа данных String.

Явные и неявные преобразования #

Значения, передаваемые переменным, можно привести в тот тип данных, которые переменная может принять. Вручную или автоматически, или явно и неявно.

преобразование типов данных

Расширение типа (widening Casting), которое можно проследить на схеме с помощью стрелок, происходит автоматически. Это преобразование меньшего типа данных в типа большего размера: byte -> short -> char -> int -> long -> float -> double.

Сужение типа (narrowing Casting) — преобразование типа данных большего размера в тип данных меньшего размера — делается вручную: double -> float -> long -> int -> char -> short -> byte

public class MyClass   public static void main(String[] args)   int myInt = 9;  double myDouble = myInt; // Automatic casting: int to double   System.out.println(myInt); // Outputs 9  System.out.println(myDouble); // Outputs 9.0  > > 
public class MyClass   public static void main(String[] args)   double myDouble = 9.78;  int myInt = (int) myDouble; // Manual casting: double to int   System.out.println(myDouble); // Outputs 9.78  System.out.println(myInt); // Outputs 9  > > 

Повышение типа на примере

public class Main   public static void main(String[] args)   byte b = 42;  char c = 'a';  short s = 1024;  int i = 50_000;  float f = 5.67f;  double d = .1234;  double result = (f * b) + (i / c) - (d * s);  System.out.println((f * b) + " + " + (i / c) + " - " + (d * s));  System.out.println("result = " + result);  > > 

Допустим, у нас имеется старая база данных, где все данные записаны в строковом виде. Например просто текстовый файл столбиком. Java даёт нам возможность “спарсить” целочисленные данные из строк.

String number = "10"; int result = Integer.parseInt(number); System.out.println(result); 

Дополнительные материалы #

  1. По ссылке можно посмотреть все методы, которые поддерживает тип данных String.

Домашнее задание #

  1. Найти в интернете таблицы для типа данных char. Проверить, что они действительно соответствуют тому, что выводит Java на экран. Найти “смешные” символы, символ стандартного смайлика, найти символ телефона, параграфа, копирайта(C), торговой марки(тм), рубля, евро, доллара, знаков зодиака, шахмат, червы.
  2. Вбить в поисковую строку Windows “charmap”.
  3. Найдите самостоятельно статьи на тему:
    • Что такое юникод?
    • Что такое ASCII?
    • Что такое UTF?
  4. Что будет, если “сложить” переменную String с самой собой? Можно ли умножить её на саму себя? Почему?
  5. Вывести на экран сообщение в кавычках. Например собственное имя + “профессия”.
  6. Вывести на экран построчно анкетные данные: Имя, Фамилия, Адрес, Улица и тд и тп. Пример вывода одной строчки:

Почему string — это char*?

Встречный вопрос на Чем отличается char* от int*, float* и других в Си? .
Насколько я знаю, string — это символьная строка (много символов, короче говоря).
Char — это один символ, символьный тип. Очевидно, что для string памяти нужно в разы больше. Так почему char* — это string, и зачем тут звёздочка (*) ?

  • Вопрос задан более трёх лет назад
  • 4658 просмотров

1 комментарий

Оценить 1 комментарий

Если изучаешь C, так ничему не научишься. C изучается обычно по книге Кернигана и Ритчи. Так и называется K&R2. И указатели там только в 5-ой главе начинаются.

Решения вопроса 1

Anton3

Я так понял, что std::string не имелся в виду.
То есть суть вопроса такова: почему строки передают как char* , хотя это тип указателя на один char .

Дело в том, что массивы в C нельзя передавать как параметр функции, указатель на массив нельзя сохранить.
В результате массив, например char[8] , принято передавать как указатель на его первый элемент: char* . Более того, при передаче массива в функцию он автоматически разлагается (decays) до указателя на первый элемент.

Остальные элементы получаются при помощи адресной арифметики: *(p+3) или p[3] , что одно и то же. Итак, указатель в коде C может указывать как на одну переменную, так и на целый массив (точнее, его начало).

Для массивов int или любого другого типа обычно вместе с указателем на первый элемент передают размер массива. Но строки C завершаются нулевым символом, поэтому здесь длина известна и так. Вот и получается, что char* используют вместо char[N] .

Edit: На самом деле, в C можно объявить указатель на массив:
int (*arr)[10] = malloc(sizeof(*arr) * 5);
Не помню, чтобы я видел такую конструкцию в реальном коде.

String или char*?

Сейчас склоняюсь к использованию char массивов, но что же лучше использовать?
И какое различие между char* и char[]?

  • Вопрос задан более трёх лет назад
  • 1099 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 2

Для хранения текста лучше используйте std::string. Не придётся следить за памятью и проще обращаться к конкретным элементам, например к последнему символу.

Итерация по всем символам тоже удобнее:

string str = "hello!"; for(auto& c: str) < c += 1; >cout 

Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Developer, ex-admin

И какое различие между char* и char[]?

char* str1 = "Hello world!";
char str2[] = "Hello world!";
Разница между str1 и str2 в том, что str1 - это lvalue, а str2 - нет.
Т.е. с str1 вы можете, например сделать str1 = str1 + 1; а с str2 нет.

С точки зрения памяти:
В случае str1 в памяти хранится 2 сущности: 1) сама строка "Hello world!" 2) указатель, которому присваивается адрес строки. Поэтому вы можете присвоить другое значение указателю.
В случае str2 указателя в памяти нет, есть только строка. Адрес строки знает компилятор и использует его когда нужно. Но присвоить новое значение этому адресу уже не возможно.
Можно считать, что char str[]; это то же что и char * const str;

Какая разница между std::string, char [] и char * [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме.

Закрыт 4 года назад .
В чем отличие между:

char s[] = "text"; char* ps = "text1"; std::string str = "text3"; 

И что лучше использовать?
Отслеживать
6,651 6 6 золотых знаков 30 30 серебряных знаков 53 53 бронзовых знака
задан 15 авг 2019 в 12:16
57 1 1 золотой знак 1 1 серебряный знак 4 4 бронзовых знака

Молоток, киянка, кувалда. Что лучше использовать? Кстати, строка 2 неверна - это указатель на константную строку, const char* ps = "text1"; .

15 авг 2019 в 12:18

В С++ лучше использовать std::string если нет причин перейти на более низкий уровень. А вообще лучше - понятие субьективное.

16 авг 2019 в 13:26

Ну, проблема в том, что в std::string и вообще в stl много подводных камней. На первый взгляд кажется, что использовать std::string проще, чем массивы символов, но в чуть сценарии использования усложняются, начинаются странные вылеты и плавающие баги. Вот и универсальная причина перейти на более низкий уровень - с инкапсуляцией в C++ плохо.

9 янв 2022 в 22:16

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

char s[] = "text"; 

Объявление массива s типа char [] и инициализация этого массива строковым литералом "text" . Т. е. s — это просто массив из пяти символов: t , e , x , t , \0 .

Вы можете менять его:

s[0] = 'n'; /* s: "next" */ 

Но не можете переприсвоить сам массив s (это же массив):

char s[] = "text"; /* OK */ s = "another text"; /* Это ошибка. */ 
char *s = "text"; /* до C++11 */ const char *s = "text"; /* начиная C++11 */ 

Объявление указателя s типа char * и присваивание ему указателя на первый элемент строкового литерала "text" . Попытка изменить этот строковой литерал ( s[0] = 'a' , например), — это неопределенное поведение.

Однако сам указатель переприсваивать можно:

const char *p = "text"; /* OK */ p = "another text"; /* OK */ 

Начиная с C++11 строковые литералы могут быть прямо присвоены только const char * (т. е. только указателям на константный char ).

std::string s = "text"; 

Создание объекта s класса std::string и присваивание ему const char * 1 . Т. е. s — это не массив и не указатель, а объект.

Класс строк в свою очередь содержит множество различных возможностей: копирование, сравнение, конкатенация, изменение, поиск подстрок и так далее. Чего строки в стиле C (массивы), конечно лишены (если не принимать во внимание ).

Использовать нужно то, что больше подходит для конкретной задачи. У каждой обговоренной выше «строки» есть свои области применения.

  1. Выполняется неявное приведение типов: присваивается не const char [N] , что является типов для всех строковых литералов, а именно указатель. Также см. оператор присваивания класса строк.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *