|
int nVar = 0; //GlobalVar
int main(int argc, char* argv[])
{
int nTest1 = nVar;
int nVar = 1; //1stLevelLocalVar
nTest1 = nVar;
{
int nTest2 = ::nVar; // can acess global var, but how to access 1stLevelLocalVar
int nVar = 2; //n2ndLevelVar
nTest2 = nVar;
}
return 0;
}
|
|
|
|
|
Here's your chance to learn that global variables are crap.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Don't do it. Never, ever reuse variable names like that. It just leads to all sorts of problems with accidentally using the wrong one.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
i just do it for test purpose
|
|
|
|
|
Without the global :: specifier i believe the name alone will get the variable at the next outer level of scope.
e.g.
int main(int argc, char* argv[])
{
int t0, t1, t2;
int v = 0;
t0 = v;
{
t1 = v+1;
int v = t1;
{
t2 = v+1;
int v = t2;
}
}
return 0;
}
...cmk
Save the whales - collect the whole set
|
|
|
|
|
There is no syntax to say "one scope outward". You can only access the global scope with a plain ::
(And obviously, don't write real code like this, your teammates will thank you)
--Mike--
Visual C++ MVP
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ
Strange things are afoot at the U+004B U+20DD
|
|
|
|
|
Like everyone said, it's a bad idea to do this, in fact, the C# compiler doesn't compile code like yours.. But the answer to your questions is to just use nVar . That'll refer to the variable in the current (or enclosing) scope.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
hi, i have a class that is defined below:
class DVertex
{
public:
DVertex(MazeNode*)
{
this->node = n;
this->parent = NULL;
this->cumulativeCost = DBL_MAX;
}
// member functions
void update(MazeNode*, double); // update the parent and cost.
double getCCost() const { return cumulativeCost; } // required to relax the node.
MazeNode& getNode() const { return *node; } // required to identify the node.
MazeNode& getParent() const { return *parent; } // required for reverse lookup.
private:
MazeNode *node;
MazeNode *parent;
double cumulativeCost;
};
now the problem is when i tried to check the value of parent, i.e.
void main()
{
DVertex v;
if (v.getParent()==NULL)
; // do something
}
this will not work..
however if i change the class to return me MazeNode*, i.e.
MazeNode* getParent() const { return parent; }
then i can do that the check.
anyone know how to check if a reference is null?
and by the way, can tell me how to change the inline constructor to something shorter? i remember seeing something like Constructor(<type> par1):var1=par1; but can't remember the exact syntax.
thanks!!
|
|
|
|
|
A reference by definition can never be null. If your method could return NULL, then you'll need to return a pointer, not a reference.
ng kok chuan wrote:
can tell me how to change the inline constructor to something shorter?
What's wrong with what's there? Is concise, easy to understand, easy to maintain... Why make it harder?
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Ryan Binns wrote:
What's wrong with what's there? Is concise, easy to understand, easy to maintain... Why make it harder?
it's just for knowledge's sake...
and thanks for clarifying the reference. so i'm not wrong when i changed everything to return pointers. now my code looks incomprehensible.. with both pointers and references... and i'm not going to go and standardize my code :p it's going to be fine as it stands.
|
|
|
|
|
To quench your thirst for knowledge
class Foo
{
int x,y;
public Foo(int _x, int _y) : x(_x), y(_y)
{}
}
And there are a few reasons to prefer this syntax to manually assigning values to members. For one, if you are initializing const or reference members, you'd have to use the above syntax. Two, using the above syntax is more efficient. If you use manual member assignment, there will be two calls (constructor and operator=) for every non-POD member, if you use the above syntax, there will be only one. For eg,
class Foo
{
string x;
public Foo(string y) : x(y) {}
}
There will be only constructor call to string with the above syntax, as the compiler calls string(const string &) for initializing x. If you do
class Foo
{
string x;
public Foo(string y)
{
x = y;
}
}
there will be two, string() and operator=() on string.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
I succeeded in obtaining a CListCtrl item info using HitTest() when the List Ctrl is owned by my current thread. But when I tried HitTest an item of a List Ctrl owned by other threads such as Explorer folder view, I failed. My code is as follows:
// current cursor pos
CPoint pt;
// Suppose pWnd is the window owned by another thread
CListView* pListView = static_cast<CListView*>(pWnd);
// Get the reference of List Ctrl
CListCtrl& listCtrl = pListView->GetListCtrl();
if(listCtrl.GetItemCount() != 0)
{
::GetCursorPos(&pt);
// Get the client pos for HitTest
pListView->ScreenToClient(&pt);
LVHITTESTINFO lvhti;
lvhti.pt = pt;
// Now do HitTest() to get the item at current cursor pos
int nItem = listCtrl.HitTest(&lvhti);
if(nItem != -1)
{
...
}
...
}
The nItem always equals to -1 even when mouse is on the list ctrl item, which indicates that the HitTest() fails.
I also tried SubItemHitTest() and even AttachThreadInput() but all seem doesn't work.
Can anyone help me solve the problem? Thanks.
|
|
|
|
|
Luckybird wrote:
when I tried HitTest an item of a List Ctrl owned by other threads such as Explorer folder view, I failed.
It's not that it's another thread - it's another process. You're passing a pointer to memory allocated in your address space, to some code executing in another address space - it cannot access the memory, and so the call fails.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
so anyway to solve the problem?
|
|
|
|
|
Not easily. You'd have to get your code inside the other process' address space. So it would have to be in a DLL, and you'd have to force the other process to load your DLL. If you're doing this with explorer.exe, you can use the SHLoadInProc() function to get explorer to load your DLL. But it's not easy.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
i have been try it out but failed. The second and third options should only be executed when there is a process running. But now i fail to write that error message so the user does not suspend a process while there is no process running. part of my code is below
<br />
int menu(void)<br />
{<br />
char iobuf[80];<br />
int choice;<br />
int i,len,valid;<br />
printf ("\n");<br />
printf ("*****************************************\n");<br />
printf ("*\t\t\t\t\t*\n*\tPROCESS CREATION \t\t*\n");<br />
printf ("=========================================");<br />
printf ("\n=\t 1: Create a process \t\t=");<br />
printf ("\n=\t 2: Suspend the process\t\t=");<br />
printf ("\n=\t 3: Resume process \t=");<br />
printf ("\n=\t 4: Shutdown the process \t=");<br />
printf ("\n=========================================\n");<br />
printf ("\n");<br />
printf("\nEnter choice (1-4): ");<br />
valid = 0;<br />
<br />
-oam-
|
|
|
|
|
mpapeo wrote:
char iobuf[80];
int choice;
int i,len,valid;
Always give your variables values when you create them. Unless this is a C program ( this is all C code, so I guess it could be ), you shouldn't declare all your variables at the top, but just before you use them.
If you're always creating the process, you'd need to keep a handle to it to suspend and resume anyhow, right ? So declare that, make it NULL, and check for NULL before showing the other options. Of course, all of this needs to be in an endless loop then, so it shows more than once. Unless you want to run it every time. Then you need to try and find the handle first.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
This is what i have,
<code>
#include <windows.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <imagehlp.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct _iobuf FILE;
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
int menu(void)
{
char iobuf[80];
int choice;
int i,len,valid;
printf ("\n");
printf ("*****************************************\n");
printf ("*\t\t\t\t\t*\n*\tPROCESS CREATION \t\t*\n");
printf ("=========================================");
printf ("\n=\t 1: Create a process \t\t=");
printf ("\n=\t 2: Suspend the process\t\t=");
printf ("\n=\t 3: Resume process \t=");
printf ("\n=\t 4: Shutdown the process \t=");
printf ("\n=========================================\n");
printf ("\n");
printf("\nEnter choice (1-4): ");
valid = 0;
while( valid == 0)
{
fgets(iobuf,sizeof(iobuf),stdin);
// remove '\n'
len = strlen(iobuf)-1;
iobuf[len] = 0;
// validate data
valid = 1; // assume valid input
for(i = 0; i < len; i++)
{
if( !isdigit(iobuf[i]))
{
printf("\nPlese enter numeric digits only (1-4)\n");
valid = 0;
}
}
}
choice = atoi(iobuf);
//scanf("%d", &choice);
return choice;
}
int main(int argc, char **argv)
{
PROCESS_INFORMATION pi; /* filled in by CreateProcess */
STARTUPINFO si; /* startup info for the new process*/
HANDLE hProcess;
DWORD lpAddr = 0;
TCHAR lpApplicationName[_MAX_PATH]="";
int result;
char ans [4]="";
int choice;
while((choice = menu())!=5)//int choice;
{
switch (choice)
{
case 1:
GetStartupInfo(&si);
lpAddr = 0;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
printf("Enter process you want to execute: ",lpApplicationName);
scanf ("%s",lpApplicationName);
printf("Process %d reporting for creation\n",GetCurrentProcessId());//print out our process ID
CreateProcess(NULL, /* lpApplicationName */
lpApplicationName, /* lpCommandLine assumes to use curent process directory*/
NULL, /* lpsaProcess */
NULL, /* lpsaThread */
FALSE, /* bInheritHandles */
CREATE_NEW_CONSOLE, /* dwCreationFlags */
NULL, /* lpEnvironment */
NULL, /* lpCurDir */
&si, /* lpStartupInfo */
&pi /* lpProcInfo */
);
hProcess = pi.hProcess;
printf("New Process ID: %d ",pi.dwProcessId);
printf("has started \n");
break;
case 2:
SuspendThread(pi.hProcess);// identifies thread to suspend
break;
case 3:
ResumeThread(pi.hProcess);
break;
case 4:
printf("\nYou are about to terminate a running process, do you want to continue ( y or n) ");
scanf ("%s",ans);
result = strcmp(ans,"y");
if (result==0)
{
TerminateProcess(pi.hProcess, 0);//identifies the process to terminate
GetLastError();
}
break;
default:
printf("\nInvalid choice: ");
}
}
return (0);
}
</code>
|
|
|
|
|
OK, so it IS a C program ? ( Not C++ )
If you want to put the menu into a seperate function ( not a bad idea ), then you need to pass in the hProcess variable, so you know if there's a process going or not.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
You mean passing it as an input?
-oam-
|
|
|
|
|
Yes, so you can check if it's NULL, and alter your options accordingly.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
I stil have the program crushing, i might be missing something
<br />
printf("\nEnter choice (1-4): ");<br />
valid = 0;<br />
while( valid == 0)<br />
{<br />
fgets(iobuf,sizeof(iobuf),stdin);<br />
len = strlen(iobuf)-1;<br />
iobuf[len] = 0;<br />
valid = 1;
for(i = 0; i < len; i++)<br />
{<br />
if( !isdigit(iobuf[i]))<br />
{<br />
printf("\nPlese enter numeric digits only (1-4)\n");<br />
valid = 0;<br />
}<br />
}<br />
}<br />
hProcess = atoi(iobuf);<br />
<br />
<br />
return hProcess;
}<br />
-oam-
|
|
|
|
|
mpapeo wrote:
I stil have the program crushing, i might be missing something
While it is a bad design, this code is syntactically correct. The "crush" your program is experiencing is in some other code. Why not single-step through the code until you get to the statement(s) in error?
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
Why comment out the scanf?
try this ...
<br />
int choice;<br />
while (true) {<br />
printf ("\n");<br />
printf ("*****************************************\n");<br />
printf ("*\t\t\t\t\t*\n*\tPROCESS CREATION \t\t*\n");<br />
printf ("=========================================");<br />
printf ("\n=\t 1: Create a process \t\t=");<br />
printf ("\n=\t 2: Suspend the process\t\t=");<br />
printf ("\n=\t 3: Resume process \t=");<br />
printf ("\n=\t 4: Shutdown the process \t=");<br />
printf ("\n=========================================\n");<br />
printf ("\n");<br />
printf ("\nEnter choice (1-4): ");<br />
<br />
scanf("%u", &choice);<br />
<br />
switch (choice) {<br />
case 1:<br />
case 2:<br />
case 3:<br />
case 4: return choice; break;<br />
default: printf("\nPlese enter numeric digits only (1-4)\n"); break;<br />
}<br />
}<br />
Now the while(true) { } loop is used, it should be used sparingly. That loop will keep iterating through the menu indefinitely. The only way to get out is to choose one of the valid options. The switch will catch options 1 through 4 and return them, anything else will show the error. The switch-case statement is very useful in this case because you can run code for each option and handle all other cases. If you choose say option 2, it'll enter at case 2 but then keep going through case 3 and then it will reach case 4, return the number 2 (stored in choice) and then break; (it's really unreachable code because the function will end at the return statement.
|
|
|
|
|
let me try chris method first
-oam-
seems as that im having slight problems
why does it takes default now after pass the hProcess
|
|
|
|