c++ - учебник - язык c
Есть ли что-то, что я могу сделать в C, но я не могу сделать на C++? (15)
Вы можете редко инициализировать массивы в C. Мне нравится использовать его для сопоставления int-> sometype для относительно плотных статических карт, где unmapped value может быть интерпретировано как 0:
int my_array[] = { [1] = 3, [4] = 2 };
printf("%d %d %d\n", sizeof my_array, my_array[0], my_array[1]);
/* prints 20, 0, 3 */
Есть ли что-то, что я могу сделать в C, но я не могу сделать на C ++? Я наткнулся на вопрос на собеседовании на сайте вопросов ...
Есть несколько вещей, которые вы можете сказать в C wihch, которых вы не можете в C ++ (поскольку C ++ имеет более строгую синтаксическую проверку, а C имеет более обширный синтаксис «устаревший»).
Кроме того, могут быть некоторые среды выполнения (O / S + library + compiler), которые поддерживают C, но не C ++, поэтому вы можете делать C на тех платформах, где вы не можете делать C ++.
В C ++ отсутствует спецификатор restrict
C99. Поэтому нет возможности сообщить компилятору выполнить оптимизацию, основанную на знании, что указатели не являются псевдонимами.
В C вы можете создавать литералы массива («составной литерал»), но на C ++ вы не можете
/* p points to the first element of an array of 4 int */
int *p = (int[]){1, 2, 3, 4};
Вы также можете создать массив с размером, еще неизвестным во время компиляции, но C ++ не имеет такой возможности («массив переменной длины»):
// create array. size is known at runtime only.
int p[rand() % 5 + 1];
Вы можете делать почти все на любом из языков программирования. Разумеется, способ выразить это будет различаться, а также количество кода, ясность кода, простота дальнейшего обслуживания. Некоторые задачи могут быть закодированы с несколькими строками в Prolog и несколькими страницами кода на C ++ и т. Д.
Некоторыми ограничивающими факторами являются доступные библиотеки, доступные компиляторы и проблемы с низким уровнем. Однако, когда вы рассматриваете C и C ++ на типичном ПК, тогда нет никакой разницы в вещах, которые могут быть выполнены в любом из них.
Если, конечно, вы не просили разницы между C и C ++, потому что эти другие люди дали вам эту идею.
Короткий ответ: нет, не совсем. См. Http://www.research.att.com/~bs/bs_faq.html#difference.
Это относится к последнему стандарту C? Оригинальный стандарт C (ANSI 1989 или ISO 1990, с обновлениями 1995 года) довольно близок к тому, чтобы быть подмножеством C ++. Есть различия, но они в основном надуманные (самое большое исключение, вероятно, состоит в том, что void * свободно конвертируется с любым указателем данных в C, но не на C ++).
Тем не менее, новый стандарт C вышел в 1999 году, спустя некоторое время после того, как я прекратил делать что-либо в самом современном C. У него появились новые функции, некоторые из которых входят в стандарт C ++ в этом году или в следующем, но не все.
char *c = malloc(sizeof(char));
действителен в C, а не C ++, т.е. автоматически линяет void*
. Это, конечно, проблема синтаксиса, а не то, что вы можете и не можете _do_ (т.е. выполнить).
... это то, что я могу сделать в C, но не в C ++.
Оба языка полностью дополняют Turing, поэтому теоретически вы можете кодировать одинаково функциональные приложения в обоих.
OTOH, C ++ не является надмножеством C. Особенно C99 имеет некоторые функции, которые C ++ не имеет. Например, назначенные инициализаторы, массивы переменной длины в структурах и как автоматические переменные. В зависимости от вашего «ничего» это может быть то, что C ++ не может сделать, кроме C.
«Если это невозможно сделать в сборке, это не стоит делать!»
ОК, юмор в сторону, я ДУМАЮ, что ОП запрашивает синтаксически, а не оперативно.
Я думаю, что есть несколько неясных вещей, которые являются законными в C (по крайней мере, C89), которые не являются законными в C ++ или, по крайней мере, устарели ... Но (если они существуют), они довольно неясны. C ++ является функционально надмножеством C.
Довольно многое. Например, в C вы можете написать код следующим образом:
void * v = 0;
char * p = v;
и вы можете создавать массивы следующим образом:
int main() {
int n = 42;
int a[n];
return 0;
}
ни один из которых не будет компилироваться под C ++.
Если критерии состоят в том, чтобы решить определенную проблему программирования, то оба выполнят работу, хотя в некоторых случаях это может быть немного проще сделать в C ++ из-за более высокого уровня абстракции
Собственно, я могу вспомнить один пример:
Когда вы создаете библиотеку (файл .lib или DLL-файл) для совместного использования другими приложениями, вам лучше использовать C вместо C ++, потому что результаты более переносимы. Вы можете сделать это в компиляторе C ++, используя блок «extern» C ».
В частности, у C ++ есть причуда, где нет стандартного соглашения для управления именами - для перевода подписи функций библиотеки в имена более низкого уровня, используемые компилятором. Например, если у вас есть функция типа «int addNumbers (int a, int b)», различные компиляторы C ++ могут перевести эту функцию в разные имена, что может привести к проблемам при импорте библиотеки. Если вы используете компилятор C или окружаете библиотеку, импортируя и экспортируя код с блоком C, хотя вы не увидите эту проблему, так как есть только один способ манипулировать именами функций в C.
Стандарт C ++ 1998 года содержит список несовместимостей с стандартом 1990 C, который составляет 13 страниц (приложение C). Конечно, это не так много, по сравнению с количеством страниц, которые описывают языки, но все еще покрывает немного земли.
Краткое описание различий, которые он перечисляет:
- Добавляются новые ключевые слова (любая C-программа, которая использует их как идентификаторы, не является C ++)
- Тип символьного литерала изменен с int на char (сравните
sizeof('a')
в C и C ++!) - Строковые литералы, сделанные const (не могут делать
char* q = expr ? "abc" : "de";
) - «Предварительные определения» удаляются с языка.
- «Совместимые типы» удаляются с языка.
- Преобразование из void * в любой другой указатель теперь требует кастинга.
- Преобразование из любого const / volatile указателя в void * теперь требует кастинга.
- «Неявные декларации» удаляются с языка.
- Выражения больше не могут создавать новые типы (как в
p = (void*)(struct x {int i;} *)0;
) - результаты некоторых выражений стали lvalues (сравните
sizeof(0, arr)
дляchar arr[100];
)
... это были первые 3 страницы Приложения C.
Если вы переходите к стандарту 1999 C, различия будут навсегда называться. Хотя C ++ 0x действительно включает некоторые из функций C99, многие из них просто неотъемлемо несовместимы, например, сложный тип.
C ++ не поддерживает именованную инициализацию члена структуры, в C вы можете сделать:
struct {int x, y; } a = {.x = 3};
Вы также можете комбинировать это с функцией, показанной Мэттом Хавенер :
struct {int a [3], b; } w [] = {[0] .a = {1}, 1 .a [0] = 2};