C++ frågor
Re: C++ frågor
Det jag tyckte var knepigt med dina push- och pop-funktioner var att du håller koll på elementet som ligger högst upp i stacken med hjälp av pekare.
Att göra jämförelsen om det är fullt i stacken eller inte t.ex. blir lite svårare då.
Att göra jämförelsen om det är fullt i stacken eller inte t.ex. blir lite svårare då.
Re: C++ frågor
Jag tror inte själva upp och nedräkningen blir fel
men den pekaren ställer till det på något annat vis
eftersom det inte går skapa ett nytt objekt med
en egen definierad stack/buffert.
men den pekaren ställer till det på något annat vis
eftersom det inte går skapa ett nytt objekt med
en egen definierad stack/buffert.
Re: C++ frågor
Det fungerar!
Lite för mycket c++ ett tag här men hade utfört push och pop
på fel stack i main därför ett underligt resultat.
Din variant testade jag också och den funkar kanonbra.
Sedan förstår jag nu tack vare din kod vad den extra
funktionen med tildetecknet är till för. Eclipse autogenererade
den och jag tog bort den.
Nu ska jag gå vidare och bygga en enkel räknemaskin med polsk notation!
M.h.a stack så klart!
Lite för mycket c++ ett tag här men hade utfört push och pop
på fel stack i main därför ett underligt resultat.
Din variant testade jag också och den funkar kanonbra.
Sedan förstår jag nu tack vare din kod vad den extra
funktionen med tildetecknet är till för. Eclipse autogenererade
den och jag tog bort den.
Nu ska jag gå vidare och bygga en enkel räknemaskin med polsk notation!
M.h.a stack så klart!
Re: C++ frågor
Har lärt mig en del nytt.
Har lite svårt att komma överens med C++, Java-utbildad som jag är.
Har försökt mig på att skapa en stränganalysator att använda till en
omvänd polsk kalkylator av enklare slag, man får inte knappa in vad som
helst utan ska helst hålla sig till syntaxen.
Exempelvis:
beräkna
(2.25 - 1) * (8 + 3.5)
knappa in
2.25 1 - 8 3.5 + *
tolken hanterar inga negativa tal än så länge och beräknar inget utan
den enbart talar om vad som knappats in. Sedan ska jag ha switch/case
för de olika symbolerna plus en funktion som gör om decimaltalstecknen
till double.
Testkörning
main
Operand
StackChar
Har lite svårt att komma överens med C++, Java-utbildad som jag är.
Har försökt mig på att skapa en stränganalysator att använda till en
omvänd polsk kalkylator av enklare slag, man får inte knappa in vad som
helst utan ska helst hålla sig till syntaxen.
Exempelvis:
beräkna
(2.25 - 1) * (8 + 3.5)
knappa in
2.25 1 - 8 3.5 + *
tolken hanterar inga negativa tal än så länge och beräknar inget utan
den enbart talar om vad som knappats in. Sedan ska jag ha switch/case
för de olika symbolerna plus en funktion som gör om decimaltalstecknen
till double.
Testkörning
Ange ett tal: 2.25 8.7 - 7 6.2 + /
entered string is : 2.25 8.7 - 7 6.2 +
digit
period
digit
digit
space
digit
period
digit
space
op
space
digit
space
digit
period
digit
space
op
space
pop d
pop p
pop d
pop d
pop s
pop d
pop p
pop d
pop s
pop o
pop s
pop d
pop s
pop d
pop p
pop d
pop s
pop o
pop s
pop
main
Kod: Markera allt
#include <string>
#include "StackChar.h"
#include "Operand.h"
using namespace std;
int main() {
Operand lineanalyzer;
StackChar symbolstack(50);
char tecken[50];
cout << "Ange ett tal: ";
cin.getline(tecken,20);
cout << "entered string is : " << tecken;
cout << NEWLINE;
cout << NEWLINE;
symbolstack = lineanalyzer.getOperand(tecken);
cout << NEWLINE;
cout << NEWLINE;
symbolstack.invert();
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
cout << "pop " << symbolstack.pop() << NEWLINE;
return 0;
}
Kod: Markera allt
#include "Operand.h"
using namespace std;
Operand::Operand() {
//cout << "En instans av Op" << NEWLINE;
}
Operand::~Operand() {
//cout << "En instans av Op har tagits bort." << endl;
}
StackChar Operand::getOperand(char tecken[]){
int charindex = 0;
bool spaceflag;
bool periodflag;
bool numberflag;
bool opflag;
StackChar symbolstack(50);
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
while(numberflag || periodflag || spaceflag || opflag){
if(opflag){
symbolstack.push('o');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(periodflag){
symbolstack.push('p');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(spaceflag){
symbolstack.push('s');
charindex++;
numberflag=number(tecken,charindex);
periodflag=period(tecken,charindex);
spaceflag=space(tecken,charindex);
opflag=operand(tecken,charindex);
}
if(numberflag){
symbolstack.push('d');
charindex++;
numberflag = number(tecken,charindex);
periodflag = period(tecken,charindex);
spaceflag = space(tecken,charindex);
opflag = operand(tecken,charindex);
}
}
return symbolstack;
}
bool Operand::number(char tecken[],int i){
bool flag = false;
if(isdigit(tecken[i])){
cout << "digit" << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::operand(char tecken[],int i){
bool flag = false;
if((tecken[i] != ' ') && (tecken[i] != '\t') && (tecken[i] != '\0')
&& (tecken[i] != '.') && (!isdigit(tecken[i]))){
cout << "op" << NEWLINE;
// if(tecken[i] == '\0')
// cout << "NULL " << tecken[i]+'0' << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::period(char tecken[],int i){
bool flag = false;
if(tecken[i] == '.'){
cout << "period" << NEWLINE;
flag = true;
}
return flag;
}
bool Operand::space(char tecken[], int i){
bool flag = false;
if((tecken[i] == ' ') || (tecken[i] == '\t')){
cout << "space" << NEWLINE;
flag = true;
}
return flag;
}
Kod: Markera allt
#include "StackChar.h"
using namespace std;
StackChar::StackChar(int stacksize) {
stackSize = stacksize;
allocbuf = new char[stacksize];
for (int i=0; i<stacksize; i++) {
allocbuf[i] = '\0'; // Initialize all elements to NULL.
}
stackTopPointer = allocbuf; // peka på element noll i allocbuf
// stackTopPointer = &allocbuf[0]; // fungerar också
bool b = allocdouble(); // allokera en stack om stacksize char
if(!b){
cout << "Allokering av stack överskred STACKSIZEMAX" << NEWLINE;
cout << "STACKSIZEMAX = " << STACKSIZEMAX << NEWLINE;
cout << STRING << NEWLINE;
}
}
StackChar::~StackChar(){
delete [] allocbuf;
//cout << "En instans av StackChar har tagits bort." << endl;
}
int StackChar::getSize(){
return stackSize;
}
void StackChar::invert(void){
int index = 0;
char c;
char temp[index];
while(index < stackSize){
temp[index] = '\0';
c = this->pop();
if(c == '\0'){
break;
}
temp[index] = c;
++index;
}
index = 0;
while(index < stackSize){
c = temp[index];
if(c == '\0'){
break;
}
this->push(c);
++index;
}
}
/**
* Allokera ett minnesområde för att lagra char.
* Avancera pekaren stackTopPointer n steg för att peka på
* start av stacken.
* Returnera true om den allokerade stacken håller
* sig inom ramen för STACKSIZEMAX annars returnera false
*/
bool StackChar::allocdouble(){
if ((allocbuf + STACKSIZEMAX - stackTopPointer) >= stackSize){
stackTopPointer += stackSize; // peka på stackens början
return true;
} else
return false;
}
void StackChar::push(char ch){
if(stackTopPointer > allocbuf){
*stackTopPointer = ch;
stackTopPointer--;
}
else{
cout << "Stacken är full" << NEWLINE;
}
}
char StackChar::pop(){
if(stackTopPointer < (allocbuf + stackSize)){
++stackTopPointer;
return *stackTopPointer;
}
else{
//cout << "Stacken är tom så " << '\0' << " returneras" << NEWLINE;
return '\0';
}
}
Re: C++ frågor
Trodde att en array måste initieras till det antal element som ska ingå
men icke. Räcker med 1.
int array[1] tar hand om fler int än ett.
int array[0] fungerar inte och
samma med int array[].
Den här koden omvandlar en radda med tecken till en double.
Anrop
Utskrift
men icke. Räcker med 1.
int array[1] tar hand om fler int än ett.
int array[0] fungerar inte och
samma med int array[].
Den här koden omvandlar en radda med tecken till en double.
Kod: Markera allt
double Operand::calcDouble(char tecken[]){
int index;
int temp;
int u = 0;
int heltal[1];
int decimaltal[1];
double decimaldel;
double heltalsdel;
double result;
for(index=0;index<10;++index){
heltal[index] = 0;
decimaltal[index] = 0;
}
index = 0;
temp = 0;
while(isdigit(tecken[index])){
heltal[temp] = tecken[index] - '0';
index++;
temp++;
}
heltalsdel = 0;
while(temp>0){
heltalsdel += pow (10,u)*heltal[temp-1];
temp--;
u++;
}
index++;
while(isdigit(tecken[index])){
decimaltal[temp] = tecken[index] - '0';
index++;
temp++;
}
decimaldel = 0;
u=0;
while(temp>0){
decimaldel += pow (10, 0-u-1)*decimaltal[u];
temp--;
u++;
}
result = 0.0;
result = heltalsdel + decimaldel;
return result;
}
Kod: Markera allt
char decimalnumber[1];
decimalnumber[0] = '6';
decimalnumber[1] = '7';
decimalnumber[2] = '.';
decimalnumber[3] = '4';
double d = lineanalyzer.calcDouble(decimalnumber);
cout << "d = " << d << NEWLINE;
for(int i = 0; i < 5; i++){
decimalnumber[i] = 0;
}
decimalnumber[0] = '.';
decimalnumber[1] = '4';
decimalnumber[2] = '5';
double f = lineanalyzer.calcDouble(decimalnumber);
cout << "f = " << f << NEWLINE;
cout << "d / f = " << d/f << NEWLINE
d = 67.4
f = 0.45
d / f = 149.778
Re: C++ frågor
Gjorde ett försök till tolk en gång i tiden.
Om nu den är värd att visa. Det finns en bugg någonstans.
"text" är en sträng.
Funktionen Berakna anropas rekursivt.
Om nu den är värd att visa. Det finns en bugg någonstans.
"text" är en sträng.
Funktionen Berakna anropas rekursivt.
Kod: Markera allt
double TForm1::Berakna(void){
double b=0, d[50], e[50];
int tal=0;
char a, t[50], u[50];
bool go=true, opr=false, minus=false;
for(int i=0; i<50; i++) {
d[i]=0;
e[i]=0;
t[i]=' ';
u[i]=' ';
}
// Tolka --------------------------------------
int len=text.Length() ;
while(go==true && pos<=len){
a=text[pos];
pos++;
if(a>='0' && a<='9') {
b= b*10 + a - '0';
opr=false;
}
else {
switch (a){
case '-':
if(opr==true) {
minus=true;
break;
}
// OBS inget break här
case '+':
case '*':
case '/':
if(minus==true) {
b=-b;
}
d[tal]=b; b=0;
t[tal]=a;
tal++;
opr=true;
minus=false;
break;
case ')':
go=false;
break;
case '(':
opr=false;
b=Berakna();
break;
}
}
}
if(minus==true) {
b=-b;
}
d[tal]=b;
t[tal]= ' ';
tal++;
// Beräkna --------------------------------------
// * och /
int k=0;
b=d[0];
for( int i=0 ; i<tal ; i++){
if(t[i]=='*'){
b=b*d[i+1];
}
else if(t[i]=='/'){
b=b/d[i+1];
}
else {
e[k]=b;
u[k]=t[i];
k++;
b=d[i+1];
}
}
// + och -
b=e[0];
for( int i=0 ; i<k ; i++){
if(u[i]=='+'){
b+=e[i+1];
}
else if(u[i]=='-'){
b-=e[i+1];
}
}
return(b);
}
//---------------------------------------------------------------------------
Senast redigerad av baron3d 16 februari 2019, 19:42:18, redigerad totalt 1 gång.
-
- Inlägg: 1397
- Blev medlem: 29 januari 2011, 21:06:30
- Ort: Lapplandet
Re: C++ frågor
Nej nej nej. Det här är helt fel. Skriver du mer än 1 int skriver du över minne som någon annan variabel använder.4kTRB skrev:Trodde att en array måste initieras till det antal element som ska ingå
men icke. Räcker med 1.
int array[1] tar hand om fler int än ett.
Språket hindrar dig inte från att accessa en array utanför gränserna (för det finns vissa specifika användningsområden) men det är en livsfarlig bugg att göra som du gör.
-
- Inlägg: 982
- Blev medlem: 2 juli 2010, 23:04:07
Re: C++ frågor
@4kTRB: Jag tror du har missuppfattat hur arrayer funkar i C. De är inte objekt som är smarta på något vis. En array har fått precis så många element som du har deklarerat, dvs. 1, i det här fallet. Tyvärr har C inte någon automatisk kontroll på att man går utanför arrayens gränser. Sen kan det ligga vad som helst bredvid den, och om arrayen är en icke-statisk lokal variabel så ligger den på CPU-stacken. Att C och C++ inte har "bounds checking" i språket anses av många som den största anledningen till varför man inte borde använda de språken.
För C++ rekommenderas klassen std::vector , som kan öka i storlek dynamiskt men du måste fortfarande ändra storlek med anrop för just det: indexera högt funkar inte.
Buffertöverskridning på Wikipedia ...
Bufferöverskridningar ("Buffer overflow") är orsaken till en stor del av alla säkerhetshål i programvara.
I C och C++ måste du alltid ha koll på dina index, storlekar och pekare!
För C++ rekommenderas klassen std::vector , som kan öka i storlek dynamiskt men du måste fortfarande ändra storlek med anrop för just det: indexera högt funkar inte.
Buffertöverskridning på Wikipedia ...
Bufferöverskridningar ("Buffer overflow") är orsaken till en stor del av alla säkerhetshål i programvara.
I C och C++ måste du alltid ha koll på dina index, storlekar och pekare!
Senast redigerad av Findecanor 15 februari 2019, 14:42:50, redigerad totalt 2 gånger.
Re: C++ frågor
> "Buffer overflow" är orsaken till en stor del av alla säkerhetshål...
Ja, det och "zero terminated strings". Glöm bort "null" och det händer
spännande saker med många minnes kopierings rutiner...
Ja, det och "zero terminated strings". Glöm bort "null" och det händer
spännande saker med många minnes kopierings rutiner...
Re: C++ frågor
Det där får du nog rita ett flödesschema på för att kunna reda ut.baron3d skrev:Gjorde ett försök till tolk en gång i tiden.
Om nu den är värd att visa. Det finns en bugg någonstans.
Re: C++ frågor
Men C är ju utformat för maskinnära programmering, är väl därför den ligger på botten av alla (flesta) operativsystem.
Sen att skylla på språket för att man inte kan hantera det är väl lite fel!
Lite förenklat så får C eller C++ programmerare (C++ är en utveckling av C) se till att städa efter sig samt se till att ha kontroll på sin minnes hantering, vilket inte är ett större problem om man vet vad man sysslar med.
Finns i tråden ett skräckexempel på minnes hantering som skriver i otillåten minnes area, rådet till dessa är att använda något högnivås språk som tar hand om dessa misstag.
Styrkan i C, C++ är att jag som programmerare har total kontroll av hårdvaran men som vid okunskap skapar problem.
C eller C++ är lite som är du verkligen mogen att ta detta ansvar eller skall du låta andra ta ansvaret?
Sen att skylla på språket för att man inte kan hantera det är väl lite fel!
Lite förenklat så får C eller C++ programmerare (C++ är en utveckling av C) se till att städa efter sig samt se till att ha kontroll på sin minnes hantering, vilket inte är ett större problem om man vet vad man sysslar med.
Finns i tråden ett skräckexempel på minnes hantering som skriver i otillåten minnes area, rådet till dessa är att använda något högnivås språk som tar hand om dessa misstag.
Styrkan i C, C++ är att jag som programmerare har total kontroll av hårdvaran men som vid okunskap skapar problem.
C eller C++ är lite som är du verkligen mogen att ta detta ansvar eller skall du låta andra ta ansvaret?
Re: C++ frågor
Visst, gör rätt så blir det rätt. Spelar ingen roll, man kommer inte
förbi att det är lättare att göra misstag (missstag har ingenting med
kompetens att göra) i C än i många andra språk/verktyg. Och det
är inte heller någon tvekan att detta har orsakat många problem
med applikationer och system. Det är bara att acceptera att det
har blivit så populärt och bita ihop...
förbi att det är lättare att göra misstag (missstag har ingenting med
kompetens att göra) i C än i många andra språk/verktyg. Och det
är inte heller någon tvekan att detta har orsakat många problem
med applikationer och system. Det är bara att acceptera att det
har blivit så populärt och bita ihop...
Re: C++ frågor
Ja är väl därför dagens programmerare föredrar ramverk som hanterar alla svårigheter som en själv lärde sig under 80 talet
Re: C++ frågor
Med kompetens så vet du vilka (skit) bibliotek som har osäkra funktioner samt hur man undviker problem.