|
|
(не показано 13 промежуточных версий 2 участников) |
Строка 1: |
Строка 1: |
− | ===Не получается сравнить два числа типа double=== | + | == Ответы на часто задаваемые вопросы по ANSI C++. == |
− | стандартный прием - задание точности:
| + | |
− | <pre>
| + | |
− | #include <math.h>
| + | |
− | double d1,d2;
| + | |
− | double acc=0.00001;//требуемая точность сравнения
| + | |
− | ...
| + | |
− | ...
| + | |
− | if( fabs(d1-d2) < acc )
| + | |
− | {
| + | |
− | //операнды равны (с точностью acc)
| + | |
− | }
| + | |
− | else
| + | |
− | {
| + | |
− | //убедились, что операнды не равны, здесь можно
| + | |
− | //смело сравнивать операторами ">" и "<"
| + | |
− | }
| + | |
− | </pre>
| + | |
| | | |
− | ===Как задать число знаков после запятой у float при преобразовании в строку?===
| + | Составлено по материалам [http://forum.shelek.ru форума программистов]. |
− | примеры для разных случаев:
| + | |
− | <pre>
| + | |
− | char sDouble[128]
| + | |
− | float d1 = 0.001778;
| + | |
− | ...
| + | |
− | sprintf(sDouble,"%.4f",d1);//4 знака после запятой
| + | |
− | ...
| + | |
− | printf("%.4f", d1);//4 знака после запятой
| + | |
− | ...
| + | |
− | cout<<setiosflags( ios::fixed )<< setprecision( 4 )
| + | |
− | << d1;//4 знака после запятой
| + | |
− | </pre>
| + | |
| | | |
− | ===Как динамически задать число знаков после запятой у float при преобразовании в строку?===
| + | <br> |
− | Если нужно вывести, к примеру, double с 5 знаками после
| + | |
− | десятичной точки, сначала нужно сформировать строку вида
| + | |
− | "%.5f", а потом задать ее в качестве спецификации формата
| + | |
− | <pre> char sDouble[128], strFormat[128]; | + | |
− | double d1 = 150.0f;
| + | |
− | int nCount;//текущее количество знаков после запятой
| + | |
− | ...
| + | |
− | nCount = 5;
| + | |
− | sprintf(strFormat, "%%.%df", nCount );
| + | |
− | //strFormat теперь содержит строку "%.5f"
| + | |
− | //форматируем:
| + | |
− | sprintf(sDouble, strFormat, d1);
| + | |
− | </pre>
| + | |
− | аналогично, если используется класс CString :
| + | |
− | <pre>
| + | |
− | CString sDouble,strFormat;
| + | |
− | ...
| + | |
− | strFormat.Format("%%.%df", nCount );
| + | |
− | sDouble.Format(strFormat, d1);
| + | |
− | </pre>
| + | |
| | | |
− | ===Как задать число знаков после запятой у float в функции printf?===
| + | #[[FAQ:ANSI CPP:сравнить два числа типа double|Не получается сравнить два числа типа double.]] |
− | В printf в спецификаторе числа разрядов можно поставить символ "*".
| + | #[[FAQ:ANSI CPP:задать число знаков после запятой|Как задать число знаков после запятой у float при преобразовании в строку?]] |
− | тогда соответствующий по порядку аргумент будет интерпретирован
| + | #[[FAQ:ANSI CPP:динамически задать число знаков после запятой|Как динамически задать число знаков после запятой у float при преобразовании в строку?]] |
− | как число знаков
| + | #[[FAQ:ANSI CPP:задать число знаков после запятой в функции printf|Как задать число знаков после запятой у float в функции printf?]] |
− | <pre> printf("%.*f", 2, 3.1415);//выведет 3.14 </pre>
| + | #[[FAQ:ANSI CPP:вывод в файл с помощью fstream|Как всё, что выводится в cout, вывести в файл?]] |
− | (для CString::Format символ "*" НЕ работает) | + | #[[FAQ:ANSI CPP:при вводе текста в переменную считываются только те символы, которые шли до пробела, а необходимо считать всю строку целиком|Как преодолеть такую ситуацию, когда при вводе текста в переменную считываются только те символы, которые шли до пробела, а мне необходимо считать всю строку целиком?]] |
| + | #[[FAQ:ANSI CPP:генерация случайных чисел от 0 до 1|Какую функцию нужно использовать для генерации случайных чисел от 0 до 1?]] |
| + | #[[FAQ:ANSI CPP:присвоение строки|Почему не получается присвоить строку?]] |
| + | #[[FAQ:ANSI CPP:передача параметров конструктору базового класса|Как из конструктора класса-наследника передать параметры конструктору базового класса?]] |
| + | #[[FAQ:ANSI CPP:обращение к переменной или методу базового класса|Как обратиться к переменной или методу базового класса?]] |
| + | #[[FAQ:ANSI CPP:генератор псевдослучайных чисел|Стандартный генератор псевдослучайных чисел.]] |
| + | #[[FAQ:ANSI CPP:проинициализировать статический член класса|Как проинициализировать статический член класса?]] |
| + | #[[FAQ:ANSI CPP:задать значение константы в двоичном представлении|Как задать значение константы в двоичном представлении (т.е. единицами и нулями в виде битового поля)?]] |
| + | #[[FAQ:ANSI CPP:преобразование строки и числа|Как можно число, представленное в символьном виде, получить (или преобразовать) в виде целочисленного типа данных? И как представить число в виде массива символов (строки)? (например CString -> int и int -> CString)]] |
| + | #[[FAQ:ANSI CPP:удалить из строки все пробелы|Как удалить из строки все пробелы при обработке строки символов в Си++?]] |
| | | |
− | ===Как всё, что выводится в cout,вывести в файл?===
| + | [[Category:FAQ]] [[Category:FAQ:ANSI_CPP]] |
− | Можно перенаправишь поток cout при запуске программы, но тогда
| + | |
− | ВСЕ сообщения пойдут в этот файл. Так что лучше открыть
| + | |
− | специальный поток для файла:
| + | |
− | <pre>
| + | |
− | #include <fstream>
| + | |
− | ...
| + | |
− | ofstream file_out (filename);
| + | |
− | ...
| + | |
− | file_out<< "текст" <<setiosflags( ios::fixed )
| + | |
− | <<setprecision( 3 )<< 3.456564 << endl;
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Как преодолеть такую ситуацию, когда при вводе текста в переменную считываются только те символы, которые шли до пробела, а мне необходимо считать всю строку целиком? ===
| + | |
− | например:
| + | |
− | <pre>
| + | |
− | char test1[20],test[20];
| + | |
− | cin>>test; //ввожу: "текст с пробелом"
| + | |
− | cout<<test; //выводится: "текст"}
| + | |
− | | + | |
− | scanf("%s",test1); //ввожу: "текст с пробелом"
| + | |
− | printf("%s",test1); //выводится: "текст"
| + | |
− | </pre>
| + | |
− | Как это обойти? Средствам доступными в TC++3?
| + | |
− | <pre>
| + | |
− | string buffer;
| + | |
− | getline(cin, buffer, '\n');
| + | |
− | cout << buffer << "|" << endl;
| + | |
− | </pre>
| + | |
− | или
| + | |
− | <pre>
| + | |
− | do
| + | |
− | {
| + | |
− | ch = getch();
| + | |
− | cout << ch
| + | |
− | }while(ch!='/0');
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Какую функцию нужно использовать для генерации случайных чисел от 0 до 1?===
| + | |
− | <pre>
| + | |
− | #include <climits>
| + | |
− | ...
| + | |
− | double betweenZeroAndOne = double(rand()) / double(INT_MAX);
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Почему не получается присвоить строку?===
| + | |
− | Например я пишу:
| + | |
− | <pre>
| + | |
− | | + | |
− | char mess[]="";
| + | |
− | ...
| + | |
− | mess="мой текст";//задаю значение строки
| + | |
− | MessageBox(hwnd, mess,"Error Message",MB_OK);
| + | |
− | </pre>
| + | |
− | | + | |
− | '''Ответ:'''
| + | |
− | Массив mess объявлен как
| + | |
− | char mess[]="";
| + | |
− | | + | |
− | то есть всё равно что
| + | |
− | char mess[1]='\0';
| + | |
− | | + | |
− | размер массива равен единице, первый элемент равен 0.
| + | |
− | | + | |
− | Чтобы присвоить строку, нужно увеличить размер массива
| + | |
− | (см. пример) и использовать strcpy для копирования
| + | |
− | содержимого "мой текст" в mess :
| + | |
− | <pre>
| + | |
− | | + | |
− | char mess[100];
| + | |
− | mess[0]=0;//инициализация
| + | |
− | ...
| + | |
− | strcpy(mess, "мой текст");
| + | |
− | </pre>
| + | |
− | Либо использовать std::string (стандартный класс работы
| + | |
− | со строками в C++).
| + | |
− | | + | |
− | ===Как из конструктора класса-наследника передать параметры конструктору базового класса?===
| + | |
− | <pre>
| + | |
− | | + | |
− | //базовый класс
| + | |
− | class parent
| + | |
− | {
| + | |
− | public:
| + | |
− | parent(int n)
| + | |
− | {
| + | |
− | }
| + | |
− | };
| + | |
− | | + | |
− | //наследник
| + | |
− | class child: public parent
| + | |
− | {
| + | |
− | child(int n,double d): parent(n)
| + | |
− | {
| + | |
− | }
| + | |
− | };
| + | |
− | </pre>
| + | |
− | ===как обратиться к переменной или методу базового класса?===
| + | |
− | если не вдаваться в права доступа (public,private,protected),
| + | |
− | то так
| + | |
− | <имя_базового_класса>::переменная;
| + | |
− | <имя_базового_класса>::метод();
| + | |
− | <pre>
| + | |
− | class Cbase
| + | |
− | {
| + | |
− | protected:
| + | |
− | int metod()
| + | |
− | {
| + | |
− | return 1;
| + | |
− | }
| + | |
− | };
| + | |
− |
| + | |
− | class Cchild:public Cbase
| + | |
− | {
| + | |
− | int metod()
| + | |
− | {
| + | |
− | return 5;
| + | |
− | }
| + | |
− |
| + | |
− | void example()
| + | |
− | {
| + | |
− | int n;
| + | |
− |
| + | |
− | //вызов Cchild::metod()
| + | |
− | n=metod();
| + | |
− |
| + | |
− | //вызов Cbase::metod()
| + | |
− | n=Cbase::metod();
| + | |
− | }
| + | |
− | };
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Стандартный генератор псевдослучайных чисел.===
| + | |
− | Алгоритм генератора псевдослучайных чисел, который поставляется вместе с стандартными библиотеками С
| + | |
− | <pre>
| + | |
− | #define RAND_MAX 32767
| + | |
− | | + | |
− | unsigned long next=1;
| + | |
− | | + | |
− | int rand(void) {
| + | |
− | next=next*1103515245+12345;
| + | |
− | return((unsigned int)(next/65536)%32768);
| + | |
− | }
| + | |
− | | + | |
− | void srand(unsigned int seed) {
| + | |
− | next=seed;
| + | |
− | }
| + | |
− | </pre>
| + | |
− | Источник: http://algolist.manual.ru/maths/generator/standard.php
| + | |
− | ===Как проинициализировать статический мембер класса?===
| + | |
− | <pre>
| + | |
− | class A
| + | |
− | {
| + | |
− | const static int m_n;
| + | |
− | const static int m_Arr[];
| + | |
− | };
| + | |
− |
| + | |
− | const int A::m_n=0;
| + | |
− | const int A::m_Arr[] ={1, 2, 5, 10, 20};
| + | |
− | </pre>
| + | |
− | ===Как задать значение константы в двоичном представлении (т.е. единицами и нулями в виде битового поля)?===
| + | |
− | можно использовать макросы, например:
| + | |
− | <pre>
| + | |
− | //МАКРОСЫ ДЛЯ ДВОИЧНЫХ ЧИСЕЛ
| + | |
− |
| + | |
− | //байт
| + | |
− | #define _b8(b) ((BYTE)(\
| + | |
− | (b&0x10000000?0x80:0)|(b&0x01000000?0x40:0)|\
| + | |
− | (b&0x00100000?0x20:0)|(b&0x00010000?0x10:0)|\
| + | |
− | (b&0x00001000?0x08:0)|(b&0x00000100?0x04:0)|\
| + | |
− | (b&0x00000010?0x02:0)|(b&0x00000001?0x01:0)))
| + | |
− | //слово
| + | |
− | #define __b16(b16) ((WORD)((_b8(((unsigned __int64)b16)>>32)<<8)|(_b8(b16))))
| + | |
− | //двойное слово
| + | |
− | #define __b32(b16H,b16L) ((DWORD)(((__b16(b16H))<<16)|(__b16(b16L))))
| + | |
− |
| + | |
− |
| + | |
− |
| + | |
− | //пример:
| + | |
− | BYTE by;
| + | |
− | by=_b8(0x01010110);// ==0x56
| + | |
− | by=_b8(0x111);// ==7
| + | |
− |
| + | |
− | WORD w;
| + | |
− | w=__b16(0x0111011011010011);//==0x76d3
| + | |
− |
| + | |
− | DWORD dwd;
| + | |
− | dwd=__b32(0x0101010110110011,0x0101111011010001);//==0x55B35ED1
| + | |
− | dwd=__b32(0x1000101110101010,0x11010101);//==0x8BAA00D5
| + | |
− | </pre>
| + | |
− | ===Как можно число, представленное в символьном виде, получить (или преобразовать) в виде целочисленного типа данных? И как представить число в виде массива символов (строки)? (например CString -> int и int -> CString)===
| + | |
− | <pre>
| + | |
− | CString txt;
| + | |
− | int n;
| + | |
− | ...
| + | |
− | txt="1234";
| + | |
− | n=atoi(txt); //CString -> int
| + | |
− | ...
| + | |
− | n=1234;
| + | |
− | txt.Format("%d",n);// int -> CString
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Как всё, что выводится в cout, вывести в файл?===
| + | |
− | Можно перенаправишь поток cout при запуске программы, но тогда ВСЕ сообщения пойдут в этот файл. Так что лучше открыть специальный поток для файла:
| + | |
− | <pre>
| + | |
− | #include <fstream>
| + | |
− | ...
| + | |
− | ofstream file_out (filename);
| + | |
− | ...
| + | |
− | file_out<< "текст" <<setiosflags( ios::fixed )
| + | |
− | <<setprecision( 3 )<< 3.456564 << endl;
| + | |
− | </pre>
| + | |
− | ===Какую функцию нужно использовать для генерации случайных чисел от 0 до 1?===
| + | |
− | <pre>
| + | |
− | #include <climits>
| + | |
− | ...
| + | |
− | double betweenZeroAndOne = double(rand()) / double(INT_MAX);
| + | |
− | </pre>
| + | |
− | ===почему не получается присвоить строку?===
| + | |
− | например я пишу:
| + | |
− | <pre>
| + | |
− | char mess[]="";
| + | |
− | ...
| + | |
− | mess="мой текст";//задаю значение строки
| + | |
− | MessageBox(hwnd, mess,"Error Message",MB_OK);
| + | |
− | </pre>
| + | |
− | MessageBox не выводит ничего - в чем ошибка?
| + | |
− | | + | |
− | Массив mess объявлен как
| + | |
− | char mess[]="";
| + | |
− | | + | |
− | то есть всё равно что
| + | |
− | char mess[1]="\0";
| + | |
− | | + | |
− | размер массива равен единице, первый элемент равен 0.
| + | |
− | | + | |
− | Чтобы присвоить строку, нужно увеличить размер массива (см. пример) и использовать strcpy для копирования
| + | |
− | содержимого "мой текст" в mess :
| + | |
− | <pre>
| + | |
− | char mess[100];
| + | |
− | mess[0]=0;//инициализация
| + | |
− | ...
| + | |
− | strcpy(mess, "мой текст");
| + | |
− | </pre>
| + | |
− | Либо использовать std::string (стандартный класс работы со строками в C++).
| + | |
− | | + | |
− | ===Как из конструктора класса-наследника передать параметры конструктору базового класса?===
| + | |
− | <pre>
| + | |
− | //базовый класс
| + | |
− | class parent
| + | |
− | {
| + | |
− | public:
| + | |
− | parent(int n)
| + | |
− | {
| + | |
− | }
| + | |
− | };
| + | |
− | | + | |
− | //наследник
| + | |
− | class child: public parent
| + | |
− | {
| + | |
− | child(int n,double d): parent(n)
| + | |
− | {
| + | |
− | }
| + | |
− | };
| + | |
− | </pre>
| + | |
− | ===как обратиться к переменной или методу базового класса?===
| + | |
− | если не вдаваться в права доступа (public,private,protected),
| + | |
− | то так
| + | |
− | <имя_базового_класса>::переменная;
| + | |
− | <имя_базового_класса>::метод();
| + | |
− | пример:
| + | |
− | <pre>
| + | |
− | class Cbase
| + | |
− | {
| + | |
− | protected:
| + | |
− | int metod()
| + | |
− | {
| + | |
− | return 1;
| + | |
− | }
| + | |
− | };
| + | |
− |
| + | |
− | class Cchild:public Cbase
| + | |
− | {
| + | |
− | int metod()
| + | |
− | {
| + | |
− | return 5;
| + | |
− | }
| + | |
− |
| + | |
− | void example()
| + | |
− | {
| + | |
− | int n;
| + | |
− |
| + | |
− | //вызов Cchild::metod()
| + | |
− | n=metod();
| + | |
− |
| + | |
− | //вызов Cbase::metod()
| + | |
− | n=Cbase::metod();
| + | |
− | }
| + | |
− | };
| + | |
− | </pre>
| + | |
− | ===Стандартный генератор псевдослучайных чисел?===
| + | |
− | Алгоритм генератора псевдослучайных чисел, который поставляется вместе с стандартными библиотеками С
| + | |
− | | + | |
− | Код:
| + | |
− | <pre>
| + | |
− | #define RAND_MAX 32767
| + | |
− | | + | |
− | unsigned long next=1;
| + | |
− | | + | |
− | int rand(void) {
| + | |
− | next=next*1103515245+12345;
| + | |
− | return((unsigned int)(next/65536)%32768);
| + | |
− | }
| + | |
− | | + | |
− | void srand(unsigned int seed) {
| + | |
− | next=seed;
| + | |
− | }
| + | |
− | </pre>
| + | |
− | Источник: http://algolist.manual.ru/maths/generator/standard.php
| + | |
− | ===как проинициализировать статический мембер класса?===
| + | |
− | <pre>
| + | |
− | class A
| + | |
− | {
| + | |
− | const static int m_n;
| + | |
− | const static int m_Arr[];
| + | |
− | };
| + | |
− |
| + | |
− | const int A::m_n=0;
| + | |
− | const int A::m_Arr[] ={1, 2, 5, 10, 20};
| + | |
− | </pre>
| + | |
− | ===Как задать значение константы в двоичном представлении (т.е. единицами и нулями в виде битового поля)?===
| + | |
− | можно использовать макросы, например:
| + | |
− | <pre>
| + | |
− | //МАКРОСЫ ДЛЯ ДВОИЧНЫХ ЧИСЕЛ
| + | |
− |
| + | |
− | //байт
| + | |
− | #define _b8(b) ((BYTE)(\
| + | |
− | (b&0x10000000?0x80:0)|(b&0x01000000?0x40:0)|\
| + | |
− | (b&0x00100000?0x20:0)|(b&0x00010000?0x10:0)|\
| + | |
− | (b&0x00001000?0x08:0)|(b&0x00000100?0x04:0)|\
| + | |
− | (b&0x00000010?0x02:0)|(b&0x00000001?0x01:0)))
| + | |
− | //слово
| + | |
− | #define __b16(b16) ((WORD)((_b8(((unsigned __int64)b16)>>32)<<8)|(_b8(b16))))
| + | |
− | //двойное слово
| + | |
− | #define __b32(b16H,b16L) ((DWORD)(((__b16(b16H))<<16)|(__b16(b16L))))
| + | |
− |
| + | |
− |
| + | |
− |
| + | |
− | //пример:
| + | |
− | BYTE by;
| + | |
− | by=_b8(0x01010110);// ==0x56
| + | |
− | by=_b8(0x111);// ==7
| + | |
− | | + | |
− |
| + | |
− | WORD w;
| + | |
− | w=__b16(0x0111011011010011);//==0x76d3
| + | |
− |
| + | |
− | DWORD dwd;
| + | |
− | dwd=__b32(0x0101010110110011,0x0101111011010001);//==0x55B35ED1
| + | |
− | dwd=__b32(0x1000101110101010,0x11010101);//==0x8BAA00D5
| + | |
− | </pre>
| + | |
− | | + | |
− | ===Как можно число, представленное в символьном виде, получить (или преобразовать) в виде целочисленного типа данных? И как представить число в виде массива символов (строки)? (например CString -> int и int -> CString)===
| + | |
− | <pre>
| + | |
− | CString txt;
| + | |
− | int n;
| + | |
− | ...
| + | |
− | txt="1234";
| + | |
− | n=atoi(txt); //CString -> int
| + | |
− | ...
| + | |
− | n=1234;
| + | |
− | txt.Format("%d",n);// int -> CString
| + | |
− | </pre>
| + | |