可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
[SOLVED]
I'm using CodeBlocks (C++) on Win10. I tried to create a simple graphic program - I downloaded a certain graphics package (graphics.h and other two files related to BGI - I added the lib in settings etc.). I tried this program but there seems to be a problem at the line marked. I ported this from Pascal (as my teacher -yes, it's about college-, only shows us Pascal programs) in a correct manner I suppose, or at least partially. The problem is certainly with the pointers (EDIT AFTER SOLVING: it wasn't!, check my answer). I'll give more details if needed.
The Question: Where I did mistakes and how to correct them (what to write, what to add, what to delete) so that it wil work fine? If there is no mistake in the code, but I NEED some files for graphics to work on my compiler, which are the files, where to get them and where to put them?
ERROR (not quite, now's a "warning"):
deprecated conversion from string constant to 'char*' [-Wwrite-strings]
(see code a bit below)
Please read: I would BE VERY GRATEFUL for a fixed version of my program. Refferences are USELESS, so unless you REALLY want to help me (thank you!), leave this page. My only related capacity is to compare two versions of a program that are intended to do the same thing but one has a mistake (or more).
CODE (updated!):
#include<iostream>
#include<graphics.h>
#include<conio.h>
using namespace std;
int main(){
int gr,xmax,ymax,r;
int gm,gd;
gd=DETECT;
gm=0;
initgraph(&gd, gm, "C:\\TC\\BGI"); /*edit(solved): followed the tutorial linked in my answer; not a directory in my PC.*/
gr=graphresult();
if(gr!=grOk) cout<<"Error!";
else {xmax=getmaxx();
ymax=getmaxy();
cout<<"Resol.: "<<xmax+1<<"x"<<ymax+1;}
setcolor(7);rectangle(0,0,xmax,ymax);setcolor(5);line(0,0,xmax,ymax);line(0,ymax,xmax,0);setcolor(3);
for(r=(ymax+1)/2;r>=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
getch();
closegraph();
return 0;
}
graphics.h source and guide: http://www.codewithc.com/how-to-include-graphics-h-in-codeblocks/
回答1:
You get an error because you try to take the address of something that isn't stored in memory.
Character literals like ' '
are basically translated into integers by the compiler, and you would not expect e.g. &32
(the ASCII code for space) to work would you?
If you're supposed to pass a string, use double-quotes and no address-of operator, as in " "
.
回答2:
Just read your edited question and want to mention about LValue:
"LValue" means something which has an address i.e. you may apply the address operator &
. LValue because it may appear on Left side of an assignment.
A variable has an address and thus is an LValue.
A character constant (e.g. 'A'
) has actually type int
and is not an LValue.
A string constant (e.g. "Hello"
) has type const char[]
(compatible to const char*
) is (may be surprisingly) an LValue because the compiler must allocate data storage for it somewhere.
Thus, even the following would "work":
#include <stdio.h>
int main()
{
char *sz = "Hello";
printf("address of \"%s\": %p\n", sz, sz);
printf("address of sz: %p\n", &sz);
sz[0] = 'h';
printf(sz);
return 0;
}
I compiled and tested with gcc and cygwin (on Windows 10 - 64 bit):
$ gcc -o test-cstringlvalue test-cstringlvalue.c
$ ./test-cstringlvalue.exe
address of "Hello": 0x403060
address of sz: 0x61cc6c
Segmentation fault (core dumped)
So you see two important things:
It compiles fine. (Changing an LValue is not suspected by the compiler.)
It crashs because a constant string has been modified.
(It probably will not crash on any platform.)
However, I recommend not to modify string constants but it demonstrates what I tried to explain about LValues.
I hope the sample does not confuse you any more. I warmly recommend to get a good C book. There are a lot of tricks possible in C but the language itself is tricky.
Edit:
Reading my own text again I felt a little bit uncertain if I told it exactly right: Thus I googled again and found this link: SO: Why are string literals l-value while all other literals are r-value?.
回答3:
I fixed the obvious syntax errors and marked the places by comment `/* <-- FIXED */:
#include<iostream>
#include<graphics.h>
#include<conio.h>
using namespace std;
int main()
{
int gr,xmax,ymax,r;
int gm,gd; /* <-- FIXED */
gd=DETECT;
gm=0;
initgraph(&gd, &gm, "C:/Users/MyName/Desktop/WORKFOLDER/"); /* <-- FIXED */
gr=graphresult();
if(gr!=grOk) cout<<"Error!";
else {
xmax=getmaxx();
ymax=getmaxy();
cout<<"Resol.: "<<xmax+1<<"x"<<ymax+1;
}
setcolor(7);rectangle(0,0,xmax,ymax);setcolor(5);line(0,0,xmax,ymax);line(0,ymax,xmax,0);setcolor(3);
for(r=(ymax+1)/2;r=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
getch();
closegraph();
return 0;
}
Unfortunately, I cannot compile and test it. (I don't have BGI libs and don't want to install it.)
回答4:
Solved!
Downgraded CB (v16 to v13 I think, not sure if it was necessary) and replaced some files.
I followed this tutorial:
https://m.youtube.com/watch?v=FxCdMM9H66I
It was quite the same as the link in the question but probably (one or more of) those files (graphics.h, winbgim.h, libbgi.a) from the previous link were bugged, had some unobvious errors or so, or were incompatible etcetera), while the files given by the maker of the vid I provided in this answer were corrected. I don't (really want to) know.
Now, the warning still appears, BUT the program runs perfectly!
I replaced r=0 with r>=0 , this was a minor mistake. (I'll update the question if I still can)
Thanks for... your help! (Can't say "nothing", I'd be mean)
:)
EDIT:
Some "cleaner" version that shows the circle (just realised the variant in the question doesn't display the filled circle):
#include<iostream>
#include<graphics.h>
#include<dos.h>
using namespace std;
main(){
int gm,gd,gr,xmax,ymax,r;
gd=DETECT;
gm=0;
initgraph(&gd,&gm,"C:\\TC\\BGI");
gr=graphresult();
if(gr!=grOk) cout<<"Error!";
else {xmax=getmaxx();
ymax=getmaxy();
cout<<"Res.: "<<xmax+1<<"x"<<ymax+1;}
setcolor(7);
rectangle(0,0,xmax,ymax);
setcolor(5);
line(0,0,xmax,ymax);
line(0,ymax,xmax,0);
setcolor(3);
for(r=(ymax+1)/2;r>=0;r--) circle((xmax+1)/2,(ymax+1)/2,r);
getch();
closegraph();
}
EDIT2:
Downgrading not necessary CONFIRMED! :D
回答5:
The warning should go away if you replace the literal with an array that can be converted to char*:
char driver[] = "";
initgraph(&gd, &gm, driver);