static在C/C++中的作用?有初始化值的作用嗎?
1.先來介紹它的第一條也是最重要的一條:隱藏
當我們同時編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。如果加了static,就會對其它源文件隱藏。
2.static的第二個作用是保持變量內容的持久。
存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不過和全局變量比起來,static可以控制變量的可見范圍,說到底static還是用來隱藏的。
3.static的第三個作用是默認初始化為0.其實全局變量也具備這一屬性,因為全局變量也存儲在靜態數據區。
在靜態數據區,內存中所有的字節默認值都是0x00,某些時候這一特點可以減少程序員的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有元素都置0,然后把不是0的幾個元素賦值。如果定義成靜態的,就省去了一開始置0的操作。
產生疑問的例子:
static char str[10]; —— 這將創建一個容量為10的字符數組。我猜static對你而言或者有些陌生,如果這樣就忽略它。這只不過會在創建數組的同時對其進行初始化。
標志在C++中的含義?
clear()函數?
清除並發隊列,銷毀所有當前已排入隊列的元素。 此方法不是並發安全方法。並發(在操作系統中,是指一個時間段中有幾個程序都處於已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行。
並發環境下,由於程序的封閉性被打破,出現了新的特點:
①程序與計算不再一一對應,一個程序副本可以有多個計算
②並發程序之間有相互制約關系,直接制約體現為一個程序需要另一個程序的計算結果,間接制約體現為多個程序競爭某一資源,如處理機、緩沖區等。
③並發程序在執行中是走走停停,斷續推進的。)
文件流句柄?
在文件I/O中,要從一個文件讀取數據,應用程序首先要調用操作系統函數並傳送文件名,並選一個到該文件的路徑來打開文件。該函數取回一個順序號,即文件句柄(file handle)。
示例1:簡單的狀態檢測
// 實際應用中可將 FileStream替換成你相應在使用的文件流句柄
if(FileStream.rdstate() == ios::eofbit)
cout << "End of file!\n";
if(FileStream.rdstate() == ios::badbit)
cout << "Fatal I/O error!\n";
if(FileStream.rdstate() == ios::failbit)
cout << "Non-fatal I/O error!\n";
if(FileStream.rdstate() == ios::goodbit)
cout << "No errors!\n";
Test.clear(ios::goodbit); //將當前狀態重置為ios::goodbit
Test.clear(ios::eofbit); // 將狀態標志設為ios::eofbit. 無實際用途.
這里都說了無實際用途,那為什么還要這樣弄呢?
形如gcount()之類的函數的頭文件及他們的用法?
gcount()之類的函數的頭文件是#include<iostream>,
形如 File.seekg(ios::beg);函數的頭文件及他們的用法?
error C2872: “move”: 不明確的符號
1> 可能是“e:\c++課設測試\c++課設測試\貪吃蛇.cpp(84) : move”
1> 或 “move”
問題解決:
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h> //使用當前時間做種子;
using namespace std;
enum dir{up,down,left,right}; //枚舉類型enum dir;
//圍牆;
class Fence
{
public:
void InitFence();
void OutputF();
public:
char game[20][20];
}f; //定義對象;
//畫框框;
void Fence::InitFence()
{
for(int i=0; i<20; i++)
for(int j=0; j<20; j++){
if(i==0||i==19||j==0||j==19)
game[i][j]= '*';
else game[i][j]= ' ';
}
}
//顯示框框;
void Fence::OutputF(){
for(int i=0; i<20; i++){
for(int j=0; j<20; j++)
cout<<game[i][j]<<' ';
cout<<endl;
}
}
//蛇結點;
class SnakeNode
{
private:
int x,y;
SnakeNode *prior,*next;
public:
void add_head(int x,int y);
int get_x();
int get_y();
void delete_tail();
}*head=NULL, *tail =NULL;
//插入頭結點;
void SnakeNode::add_head(int x,int y)
{
SnakeNode *q=new SnakeNode;
q->x =x; q->y =y;
q->next =head;
q->prior =NULL;
if(head) head->prior =q;
head =q;
if(!tail) tail =head;
f.game[x][y]= '*'; //f對象可以在定義Fence類時定義; 且Fence類在SnakeNode類前定義;
}
int SnakeNode::get_x()
{
return x;
}
int SnakeNode::get_y()
{
return y;
}
//刪除尾結點;
void SnakeNode::delete_tail()
{
SnakeNode *p =tail;
f.game[tail->get_x()][tail->get_y()]= ' ';//把尾結點的坐標表示的'*'置為空格;
if(tail==head)
tail= head= NULL;
else{
tail= tail->prior;
tail->next= NULL;
}
delete p;
}
//yidong移動;
class yidong
{
public:
dir point; //枚舉變量point: 控制方向;
int food_x;
int food_y;
public:
void moving();
void change_point(char); //改變方向;
void get_food();
};
void yidong::moving()
{
int a,b;
a= head->get_x(); //取得頭結點橫坐標
b= head->get_y(); //頭結點縱坐標
switch(point){
case dir::up: --a; break;
case dir::down: ++a; break;
case dir::left: --b; break;
case dir::right: ++b; break;
}
if(a==19||b==19||a==0||b==0)
{ //判斷是否撞牆;
cout<<"game over!!!"<<endl;
exit(0);
}
if(a==food_x && b==food_y)//吃food;
{
head->add_head(a,b);
get_food();
}
else{
head->add_head(a,b); //插入頭結點;
head->delete_tail(); //刪除尾結點;
}
}
void yidong::change_point(char keydown){
switch(keydown){
case 'w': point= dir::up; break;
case 's': point= dir::down; break;
case 'a': point= dir::left; break;
case 'd': point= dir::right; break;
}
}
void yidong::get_food(){
srand((unsigned int) time(NULL)); //做種子(程序運行時間);
food_x= rand()%18+1;
food_y= rand()%18+1;
f.game[food_x][food_y]= '*';
}
//main();
int main(){
cout<<"Using 'w,s,a,d'to control direction!!!\n\n\n";
//畫框框和小蛇;
yidong m;
f.InitFence();
head->add_head(4,3);
head->add_head(4,4);
head->add_head(4,5);
m.get_food();
f.OutputF();
while (true){
char keydown= getch(); //getch()返回鍵盤上讀取的字符;包含頭文件<conio.h>
m.change_point(keydown);
while(!kbhit()){ //判斷有沒有按鍵落下;
system("cls"); //清屏函數;
m.moving();
f.OutputF();
Sleep(200);
}
}
return 0;
}把上面這個程序中的move替換為yidong后就好了,我想想和或許是因為move是軟件的內部定義的,不能有程序員自己來定義。
error C3861: “strcmp”: 找不到標識符的解決方法就是加頭文件:#include<string.h>
: error C3861: “shijian”: 找不到標識符:說明這個函數在要調用它的函數的后面,而其沒有聲明;還有可能就是這個函數被調用了,但是在程序中根本就沒有這個函數。(注意:錯誤的是函數的形式,而不是變量的形式)
void shijian()//輸出銷售本產品是的時間
{
struct tm when;
time_t now;
time(&now);
when=*localtime(&now);
printf(" %s\n",asctime(&when));
}感覺含神奇啊?
getchar();和 getch();的區別?還有他們的用法?作用?
fscanf與scanf的區別?
scanf從鍵盤輸入 fprintf(格式化輸出數據至文件)
fscanf從文件輸入 fscanf(格式化字符串輸入)
printf(格式化輸出數據) sacnf(格式化字符串輸入)
sprintf(格式化字符串復制) sscanf(格式化字符串輸入)
在我的ACM中有文件
dat和txt的區別?
goto語句的作用范圍?
變控制流,無法通過本身返回。要用goto返回,可以定義多個label,在不同位置配合不同label使用goto語句。
label在函數內定義,作用域就是整個函數,和其它名稱一樣無法改變。由於不是左值,它沒有生存期,僅在編譯期有意義。
C/C++語言中可以放在賦值符號左邊的變量,即具有對應的可以由用戶訪問的存儲單元,並且能夠由用戶去改變其值的量。左值表示存儲在計算機內存的對象,而不是常量或計算的結果。或者說左值是代表一個內存地址值,並且通過這個內存地址,就可以對內存進行讀並且寫(主要是能寫)操作;這也就是為什么左值可以被賦值的原因了。相對應的還有右值:當一個符號或者常量放在操作符右邊的時候,計算機就讀取他們的“右值”,也就是其代表的真實值。簡單來說就是,左值相當於地址值,右值相當於數據值。右值指的是引用了一個存儲在某個內存地址里的數據。
內存地址,指系統 ram 中的特定位置,通常以十六進制的數字表示。
Run-Time Check Failure #3 - The variable 'hitkey' is being used without being initialized.?這句話的意思是使用了未被初始化的hitkey.當出現中斷時只要把此初始化即可。
continue;break;return的區別?
break 跳出總上一層循環,不再執行循環(結束當前的循環體)
continue 跳出本次循環,繼續執行下次循環(結束正在執行的循環 進入下一個循環條件)
return 程序返回,不再執行下面的代碼(結束當前的方法 直接返回)
strcat?注意string頭文件中幾種函數的用法?
fwrite(&library.count,sizeof(int),1,fp);的用法?
fflush(stdin);是什么意思?它的作用和用法?頭文件?
用來清空輸入緩存,以便不影響后面輸入的東西
清除緩沖區。比如你逐個輸入字符,他幫你緩沖掉你每輸入一個字符后面所敲的回車鍵。否則回車也會被當成字符保存進去
error C3872: “0x3000”: 此字符不允許在標識符中使用?
0x3000是漢語的空格,也就是全角空格,相當於一個漢字,但你又看不見它。
你知道的,像逗號,有半角(,)和全角(,)之分的,其實空格也有。
0x3000是全角的空格,0x20是半角的空格。
你最好把這個語句的后面空白部分,都刪除掉,免得有不可見的全角空格。
C2064: 項不會計算為接受 0 個參數的函數?
例如:
temp3=100*(x1*x1-x2)*(x1*x1-x2)+(1-x1)(1-x1),錯誤就在這里,應該是:
temp3 = 100*(x1*x1-x2)*(x1*x1-x2)+(1-x1)*(1-x1),最后這個括號前少了個乘法符號
C++課設測試.exe 中的 0x00fb1ce2 處有未經處理的異常: 0xC0000005: 讀取位置 0x33622954 時發生訪問沖突?(這好像是內存分配的問題)
原因解析:
關於0xC0000005問題:
0xC0000005: Access Violation錯誤調試- -
1》數據越界或是定義的指針未釋放.
2》空的指針的可能性最大。使用指針前最好能顯式的賦值!
應該是指針的問題
3》內存訪問錯誤,檢查指針,是否為空,是否越界等
可能性 3 種
1:
char *p;
p = new char[number];
delete [] p;
....
// always using p....
p = xxx; // access violation
2:
char *p;
memcpy(p, xxx, number); // access violation
3:
char *p;
p = new char[number];
delete [] p;
.........
delete [] p; // access violation
錯誤處理:
數據越界,argv[0]中有漢字。其實問題就是如何解決wcout輸出漢字
修改如下:
#include "stdafx.h"//在stdafx.h添加#include <iostream> #include<locale>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"argc="<<argc<<endl;
wcout.imbue(locale("chs"));
for(int i=0;i<argc;i++)
{
wcout<<"argv[0]="<<argv[0]<<endl;
}
cin.get();
return 0;
}
辨別:
1.cout在設計時具有智能判斷功能,不論是char*類型,還是string類型,都能得到正確的結果。
2.wcout指定要輸出寬字符,每個字符占兩個字節,我們所用的字符串如:"hello",要想讓其按寬字符處理,必須加L,即L"hello",中文也是這樣要求。
3.GCC編譯器不支持wcout關鍵字。
fwrite(&stud,sizeof(STUDENT),1,fp);和 fread(&stud,sizeof(STUDENT),1,fp);的用法?
1.函數功能
用來讀寫一個數據塊。
2.一般調用形式
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
3.說明
(1)buffer:是一個指針,對fread來說,它是讀入數據的存放地址。對fwrite來說,是要輸出數據的地址。
(2)size:要讀寫的字節數;
(3)count:要進行讀寫多少個size字節的數據項;
(4)fp:文件型指針。
注意:1 完成次寫操(fwrite())作后必須關閉流(fclose());
2 完成一次讀操作(fread())后,如果沒有關閉流(fclose()),則指針(FILE * fp)自動向后移動前一次讀寫的長度,不關閉流繼續下一次讀操作則接着上次的輸出繼續輸出;
3 fprintf() : 按格式輸入到流,其原型是int fprintf(FILE *stream, const char *format[, argument, ...]);其用法和printf()相同,不過不是寫到控制台,而是寫到流罷了。注意的是返回值為此次操作寫入到文件的字節數。如int c = fprintf(fp, "%s %s %d %f", str1,str2, a, b) ;str1:10字節;str2: 10字節;a:2字節;b:8字節,c為33,因為寫入時不同的數據間自動加入一個空格。
文件使用之后一定要關閉,否則將不能正確顯示內容.fwrite:讀入兩個學生信息然后用fwrite存入文件
fread:用fread從文件中讀出學生信息。
clrscr();的頭文件和用法?
清除文本模式窗口 清屏的意思 就是把之前顯示出的文字字符去掉 跟cmd里面的清屏的功能是一樣的 實際上是clear screen的簡寫
#include<conio.h>
strcmp的用法?作用?頭文件?還有和這相似的幾個函數的用法?
原型:int?strcmp(char?*str1,char?*str2)?
功能:把兩字符串str1與str2進行比較,當str1>str2,函數返回1,當str1==str2時,函數返回0,當str1<str2時函數返回-1;
在我的ACM中有文件
cprintf的用法?
函數名: cprintf
功 能: 送格式化輸出至屏幕
用 法: int cprintf(const char *format[, argument, ...]);
頭文件: conio.h
this指針的用法?
在我的ACM中有文件
內存的動態分配?
在我的ACM中有文件
gets函數的用法?
Run-Time Check Failure #3 - The variable 'stu_num' is being used without being initialized.?
在調試的時候顯示:Cannot find or open the PDB file 是怎么回事?
工具?選項?調試?符號?windows符號服務器打鈎,就可以了!
C語言經典代碼.vcxproj -> E:\C語言經典代碼\Debug\C語言經典代碼.exe 是什么意思?
%運算符為什么不能夠使用double型,只能夠使用int型?
二分法?用法?作用?
正在創建“Debug\C語言經典代碼.unsuccessfulbuild”,因為已指定“AlwaysCreate” 是什么意思?
Windows 已在 C語言經典代碼.exe 中觸發一個斷點。
其原因可能是堆被損壞,這說明 C語言經典代碼.exe 中或它所加載的任何 DLL 中有 Bug。
原因也可能是用戶在 C語言經典代碼.exe 具有焦點時按下了 F12。
輸出窗口可能提供了更多診斷信息。 這是怎么了?
stricmp(p,"end")的作用?用法?頭文件?
“exit”: 沒有重載函數接受 0 個參數 是因為exit(); 應該改為exit(1); 或exit(0);
現在主要的是他們的區別是?
program files\microsoft sdks\windows\v7.0a\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800 ???
引用了標簽,但是為對其進行定義???
window(2,2,79,24);
textbackground(LIGHTGREEN);
textcolor(YELLOW);
clrscr();
這些東西的頭文件是??作用??用法??
fatal error C1083: 無法打開包括文件:“d3d8.h”: No such file or directory???
“this”: 只能在非靜態成員函數的內部引用???
“->next”的左邊必須指向類/結構/聯合/泛型類型???
scanf("%s",d); 和scanf("%s",&d);的區別??
scanf("%s",d); 和scanf_s("%s",d);的區別???為什么有的時候用scanf_s("%s",d);不報錯,但是就是不能夠實現函數???
printf(">>產品號:%d\n",emp[i].no);
printf(">>產品名:%s\n",emp[i].name);
printf(">>**品牌:%s\n",emp[i].kind);
printf(">>**價格:%f\n",emp[i].price);
printf(">>**數量:%d\n",emp[i].num); 輸出的是一大串很奇怪的燙字???
答案:這個問題有可能是少加了一個花括號。
C++課設測試.exe 中的 0x00a22338 處有未經處理的異常: 0xC0000005: 讀取位置 0x335c1930 時發生訪問沖突???
C++課設測試.exe 中的 0x002b2381 處有未經處理的異常: 0xC0000005: 讀取位置 0x33472114 時發生訪問沖突???
Windows 已在 C++課設測試.exe 中觸發一個斷點。
其原因可能是堆被損壞,這說明 C++課設測試.exe 中或它所加載的任何 DLL 中有 Bug。
原因也可能是用戶在 C++課設測試.exe 具有焦點時按下了 F12。
輸出窗口可能提供了更多診斷信息。???
error C2541: “delete”: 不能刪除不是指針的對象???
C++課設測試.exe 中的 0x755a812f 處有未經處理的異常: Microsoft C++ 異常: 內存位置 0x0030e8fc 處的 std::bad_alloc。 這是為什么呢???
當程序中斷時出現
pvBlk = _heap_alloc_dbg_impl(nSize, nBlockUse, szFileName, nLine, errno_tmp
這是為什么???
break、return和c的區別和用法?他們的作用分別是什么???
getche();的作用和用法???
不是所有的控件路徑都返回值???
1、簡介:vc編譯時報這個警告,雖然不是錯誤,可是這確實一個不折不扣的bug。
2、產生原因:帶返回值的函數在最后沒有return x。
3、后果:調用這個函數時得到的返回值不一定是正確的。
4、實質:如果非void返回值的函數在結尾沒有return,運行時程序如果需要在最后return,則將距離函數尾部最近的return作為該函數的結尾return。
5、臨床表現:程序運行時有時候是正確的,有時候又是錯誤的,當某種條件符合時(就是肯定運行到函數尾部),這種錯誤就一直出現。
typedef的用法???
例如:typedef int size;
此聲明定義了一個int的同義字,名字為size。注意typedef並不創建新的類型。它僅僅為現有類型添加一個同義字。你可以在任何需要int的上下文中使用size:
其實typedef的主要作用就是為了提高程序的可讀性和以后好維護程序。它的作用在很多方面都比宏定義要好。
VS2010無法打開源文件<graphics.h> ??
嗯,這個是非常正常的,因為這個頭文件不是微軟的編譯器的,在tc下才有這個頭文件
找不到標示符???
只要加上相應的頭文件就可以了
LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 文件無效或損壞????
終極解決方案:
VS2010在經歷一些更新后,建立Win32 Console Project時會出“error LNK1123” 錯誤,解決方案為將 項目|項目屬性|配置屬性|清單工具|輸入和輸出|嵌入清單 “是”改為“否”即可,但是沒新建一個項目都要這樣設置一次。
在建立VS2010 Win32 Project項目時,按照上面解決方案依然發生了“error LNK1123”錯誤,經過上網查資料,解決方案為:
第一步:與上相同。
第二步:將 項目|項目屬性|配置屬性|連接器|清單文件|嵌入清單 “是”改為“否”。
第三步:一般計算機經過上兩步設置就能解決問題了,但是如果還有問題,那就按一下方法解決:
計算機是否為64bit操作系統,如是,繼續2。
查找是否有兩個cvtres.exe。一個是C:\Program Files(x86)\Microsoft Visual Studio 10.0\vc\bin\cvtres.exe, 另一個是C:\Windows\Microsoft.NET\Framework\v
4.0.30319\cvtres.exe。右鍵屬性|詳細信息 查看兩者版本號,刪除/重命名較舊的版本,或者重新設置Path變量。
意外的是,治本的辦法是第三步,刪除舊版本的cvtres.exe后,就不需要每次都設置配置了。
不允許使用繼承成員???
在類的定義中增加該函數的定義,並在最前面加上virtual關鍵字。
“CreateList”: 不是所有的控件路徑都返回值???
應該指的是函數中有些分支語句沒有加return;
“!=”: 運算符不起任何作用;應輸入帶副作用的運算符???
如果表達式語句在表達式頂部有一個沒有任何副作用的運算符,則它可能是錯誤。
若要重寫此警告,請將表達式置於圓括號中。
int scanf(const char *,...)”: 無法將參數 1 從“ElemType *”轉換為“const char *”???
在C++中建單鏈表時為什么一般都要用到(typedef int elemtype)???
無非就是為了將來修改方便,現在是int,將來如果想變成long或者其他的,直接修改typedef int elemtype;為typedef long elemtype; 就可以了。
cpp(4) : error C2447: “{”: 缺少函數標題(是否是老式的形式表?) vc2008???
前面多了分號。
error C2664: “BOOL CDC::TextOutW(int,int,const CString &)”: 不能將參數 3 從“const char [18]”轉換為“const CString &”???
1 在要輸出的字符串前面加上_T()測試宏,或者TEXT()宏,如:pDC->TextOut(10,10,_T("這是一個MFC程序!"));
如 L"我的字符串"表示將ANSI字符串轉換成unicode的字符串,就是每個字符占用兩個字節。
strlen("asd")=3;
strlen(L"asd")=6;
二、 _T宏可以把一個引號引起來的字符串,根據你的環境設置,使得編譯器會根據編譯目標環境選擇合適的(Unicode還是ANSI)字符處理方式
如果你定義了UNICODE,那么_T宏會把字符串前面加一個L。這時 _T("ABCD") 相當於 L"ABCD" ,這是寬字符串。
如果沒有定義,那么_T宏不會在字符串前面加那個L,_T("ABCD") 就等價於 "ABCD"
三、TEXT,_TEXT 和_T 一樣的
如下面三語句:
TCHAR szStr1[]=TEXT("str1");
char szStr2[]="str2";
WCHAR szStr3[]=L("str3");
那么第一句話在定義了UNICODE時會解釋為第三句話,沒有定義時就等於第二句話。
但二句話無論是否定義了UNICODE都是生成一個ANSI字符串,而第三句話總是生成UNICODE字符串。
為了程序的可移植性,建議都用第一種表示方法。
但在某些情況下,某個字符必須為ANSI或UNICODE,那就用后兩種方法。
vc2010MFC對話框:IntelliSense: 沒有與這些操作數匹配的 "+" 運算符???
因為4nChar是UNIT類型的,而m_strline是CString類型的,不e同類型的不r能進行加減、賦值等操作。改成m_strLine+=(char)nChar就行了j kw
vSQL="INSERT INTO jbxxinfo(YGid,YGname,Sex,Degree)VALUES(\'"+YGid+"\',\'"+YGname+"\',\'"+Sex+"\',\'"+Degree+"\')"; /////需要轉義標識符
無法將參數 1 從“const char [10]”轉換為“const wchar_t *”與指向的類型無關;轉換要求 reinterpret_cast、C 樣式轉換或函數樣式轉換
pure specifier can only be specified for functions???
出錯的代碼位於Priority.hh中,代碼為:
static const int MESSAGE_SIZE = 8;
這個錯誤改起來很簡單,只要將這行代碼改為:
static const int MESSAGE_SIZE;
然后定位到Priority.cpp文件中,添加以下代碼:
const int Priority::MESSAGE_SIZE = 8;
主要是因為VC6.0不支持的原因。
'CInput' : 'operator =' function is unavailable???
undefined???未被定義的
對,提示是變量定義問題,必須在同一個地方定義!
cannot access protected member declared in class ???
不能訪問受保護的成員在類聲明
see declaration of 'CStudent::CStudent'???
class Student
{
public:
int age;
Student(int a = 10);
};
Student::Student(int a = 10)
{
}
改法:
Student::Student(int a )
{
}
uses undefined class???
使用未定義的類
今天遇到了這樣的錯誤:error C2079: 'xxx' uses undefined class 'yyy'
不得不承認自己有土鱉的基因。本來是很普通的一件事情。
自己居然不知道。
剛好碰到網上一個達人的分析文章,覺得非常經典的分析了這個經典的問題。固轉載如下:
比如說,我們先定義一個b類再定義一個a類,a的一個成員就是b,如下:
class b{
int i;
};
class a {
b val ;
};
這顯然是可以的。
如果這個時候,要把b的定義放到后面去,大家都知道在前面先聲明b,那么:
class b;
class a {
b val ;
};
class b{
int i;
};
這段對不對呢?如果不編譯,直觀感覺,我以前總以為是可以的。。
但其實是通過不了編譯的。那么再改,把val換成對b的指針,這樣:
class b;
class a {
b * val ;
};
class b{
int i;
};
然后就可以了。
那么,直接給出一條重要的結論:
超前引用不可使用類名來定義變量和函數的變量參數,只可用來定義引用或者指針。
要解釋其實是很簡單的,因為編譯器在處理類的時候,要為他的成員分配空間。
如果我們用指針,那么直接分配4個字節就可以了,就像:
class b;
class a;
class a {
b *val ;
};
class b{
a *val ;
};
但是,如果成員變量是類呢??
class b;
class a;
class a {
b val ;
};
class b{
a val ;
};
這種情況下,就好比把兩面鏡子對着放置一樣。。
當處理到a的val的時候,發現是個b,那么給b留出空間,
為了知道給b留出多少空間,再看b,發現b的val是a,
那么又需要再知道該給a多少空間。。。
這個道理其實是很顯然的。
所以,VC編譯的時候說'xxx' uses undefined class 'yyy' 。
也許你覺得這些是很顯然的事情,自己寫的時候不會犯這種傻。
那么要小心的就是STL了。比如說你list <myClass>。
而這個時候myClass是處於已定義狀態,則沒有問題。
如果這個時候myClass是處於聲明狀態,則會有很大的問題。
而VC6對STL報錯的囧況,想必用過的人都知道。
往往都是一大堆,要從中提取有用的信息很不容易。
唉。。也許是我入門看的資料太瓜了。。雖然超前聲明這個概念到處都提,
卻沒怎么見有人專門指出這點。。看來有時間還是要從頭學學國外名著了。。。
今天發現這個問題,也是因為我們助教給的一堆接口及實現。
我現在真的是嚴重懷疑他究竟有沒有編譯通過。。。改了我半天。。
就算他通過了,也是儼然一不標准的用法。明顯是留有邏輯黑洞的隱患的。
眾所周知,VS可以編譯好些VC不能編譯的東西。。
原因是放寬了對標准的審核
又眾所周知,DEV可以編譯好些VC不能編譯的東西。。
原因是VC對C++的有些標准實現上有問題
超前引用不可使用類名來定義變量和函數的變量參數,只可用來定義引用或者指針。
要解釋其實是很簡單的,因為編譯器在處理類的時候,要為他的成員分配空間。
如果我們用指針,那么直接分配4個字節就可以了,就像:
class b;
class a;
class a {
b *val ;
};
class b{
a *val ;
};
error C2660: “strcpy_s”: 函數不接受 2 個參數???
代碼:
char data[256] = {0};
strcpy_s(data, "aaaaaa");
這個代碼在xp系統里是正常的,我把代碼拷貝到wince下編譯出錯,信息如下:
error C2660: “strcpy_s”: 函數不接受 2 個參數 wince
我看了一下,需要3個參數
改成 strcpy_s(data, 255, "aaa"); 就編譯通過了,啥原因?XP系統和Wince下不能同樣的寫??
rogerwu wrote:
strcpy_s((char *)deviceName, sizeof(deviceName), volumePath);???
redefinition; different basic types???發生了重定義
syntax error : 'bad suffix on number語法錯誤:“壞后綴的數字 很有可能是數字的格式出現了錯誤或者是多少了什么東西。
A:strcpy函數為什么要返回char*?
B:如果不返回 char*,還能返回什么呢?你想讓它返回什么?
A:數組
B:C/C++ 語言的參數傳遞和返回值都不可能是數組,因為在 C/C++ 中數組的內部表示就是指針,數組本身沒有長度信息,不可能作為參數或返回值。
L"Buffer is too small"&&0 意思是緩沖區太小
strcpy_s函數的用法???
比如strcpy_s(str1,count,str2);為了方便起見,這里將數組大小定義為常數count。strcpy_s函數的第一個參數是目標字符串,將源字符串向這個目標字符串復制給第三個參數。第二個參數是目標位置上可用的字節總數(包括\0等)。
看名字明白,它和strcpy()函數的功能應該一樣的。strcpy函數,就象gets函數一樣,它沒有方法來保證有效的緩沖區尺寸,所以它只能假定緩沖足夠大來容納要拷貝的字符串。在程序運行時,這將導致不可預料的行為。用strcpy_s就可以避免這些不可預料的行為。
這個函數用兩個參數、三個參數都可以,只要可以保證緩沖區大小。
三個參數時:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
兩個參數時:
errno_t strcpy_s(
char (&strDestination)[size],
const char *strSource
); // C++ only
例子:
#include "stdafx.h"
#include<iostream>
#include<string.h>
using namespace std;
void Test(void)
{
char *str1=NULL;
str1=new char[20];
char str[7];
strcpy_s(str1,20,"hello world");//三個參數
strcpy_s(str,"hello");//兩個參數但如果:char *str=new char[7];會出錯:提示不支持兩個參數
cout<<"strlen(str1)"<<strlen(str1)<<"strlen(str)"<<strlen(str)<<endl;
printf(str1);printf("\n");
cout<<str<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Test();
return 0;
}
輸出為:
strlen(str1): 11
strlen(str): 5
hello world
hello
char p_str[STR_LEN];
char* encrypt(char pw[],char key[],bool jiami,char pwout[STR_LEN])
{
ZeroMemory(pwout,STR_LEN);//返回值初始化
strcpy_s(p_str, tt);//這行不出錯,
strcpy_s(pwout, tt);//這行編譯能不過,說不能用2個參數
return p_str;//輸出的char實際上不是原來的字符,而是字符的16進制碼
}
void test()
{
char* p_str = new chae[256];
char* tt = new chae[256];
//循環給tt賦值
strcpy_s(p_str,strlen(tt), tt);//這個地方變換多種格試置換也不行
}
strcpy_s(destination, sizeof (destination) / sizeof (destination[0]), source);
debug assertion failed???
調試斷言失敗
按F5調試下,然后關掉,看看會停在哪里,之后看看調用堆棧,就知道哪里出問題了
這一般是堆棧空間分配的時候造成的
網上牛人的回答是:“你需要的不是進去,而是出來,因為format已經是null了,你再繼續執行只能是繼續錯誤,沒有什么意義 在你ide里找一個叫call stack的窗口(沒有就在按鈕上找,有個同名按鈕,點一下就出來),找到后向調用層次上面走,看看你到底哪個函數調用了這個函數,並傳遞錯誤的參數了”
簡單的講,就是程序出現了野指針或者是變量沒有初始化,出現內存泄露了。此時我按照上述牛人的方法去修改,發現問題出現在MFC本身提供的函數身上。一般而言,此時如果你是菜鳥,修改系統提供的函數是不明智的。但是信息沒有提示我編寫的代碼有問題,但是,可以明確的說,不要懷疑編譯軟件,問題肯定在你自己身上,除非你的編譯軟件連其它正確的程序也不能編譯。於是我去查對話框中的變量,一個一個去查,這才發現,單選框中定義了int型變量,這就有可能出現空指針,編譯就會報錯,一般來說你忽略這個錯誤還能運行,但我們不能因為忽略錯誤還能運行而不去管它,這對你學VC++是沒有好處的。
解決此問題的辦法:將沒有用到的這幾個int型變量刪除,或者不在Debug環境下編譯,在Release環境下編譯。這是因為在MFC中,大量使用了ASSERT宏,這些宏通常可以來糾正一些錯誤,如還沒有初始化指針就使用等。在Release方法下,ASSERT宏不會執行,所以也沒有錯誤信息。
補充一下,MFC中的ASSERT宏有時管得有點寬,如果確認沒有錯誤,也可以不理會它。
warning C4018: “<”: 有符號/無符號不匹配
出錯代碼 for(int j=0;j<detector.size();j++)
錯誤改正 : 定義j為unsigned 類型后就可以了
即: for(unsigned int j=0;j<detector.size();j++)
問題出在函數fopen_s上,
原先用fopen帶兩個參數,但是不安全
我改為fopen_s后需要三個參數,
請問fopen_s的用法是怎么樣的?我查不到
error C2440: “=”: 無法從“errno_t”轉換為“FILE *”
1> 從整型轉換為指針類型要求 reinterpret_cast、C 樣式轉換或函數樣式轉換
這里的errno_t表示什么錯誤?
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );
C/C++ code
if((fp=fopen_s(&fp,"filename","w"))==NULL)
-->
if(fopen_s(&fp,"filename","w") != 0)
fopen_s返回得是errno_t類型
不能賦值給FILE*類型
應該這樣
errno_t err;
if( (err = fopen_s( &fp, "filename", "w" )) !=0 )
LINK : fatal error LNK1168: cannot open Debug/EX_HelloWin.exe for writing???
打開任務管理器,找到EX_HelloWin.exe這個進程, 關閉它。 然后重新編譯連接。 一般這種情況意味着你的程序上一次運行並沒有正常關閉。
missing storage-class or type specifiers???
失蹤的存儲類或類型說明符
導致你定義的對象無效missing storage-class or type specifiers
原因可能是
1.沒包含相應的頭文件
2.類名拼寫出錯
MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CRightView::classCRightView" (?classCRightView@CRightView@@2UCRuntimeClass@@B)
????
把文件重新加入到工程中。工程-》添加到工程-》文件
‘initializing' : cannot convert from 'class CDocument *' to 'class CEx7_2_201300824129Doc *'???
CEx7_2_201300824129Doc* pDoc=GetDocument();改為CEx7_2_201300824129Doc* pDoc=(CEx7_2_201300824129Doc*)GetDocument();
which is being defined這是定義
以上代碼編譯提示錯誤,a' : uses 'A', which is being defined。
如果把a換成*a就可以了。
undeclared identifier
沒有定義;未說明的標志符
use of undeclared identifier 類型轉換失敗
Messagebox和AfxMessageBox的區別???
AfxMessageBox是MFC庫提供的全局函數,提供了多種重載形式,而MessageBox是標准的windows Api函數.
AfxMessageBox()函數在任何類里邊都可以使用,而MessageBox()函數只能在CWnd類的繼承類中使用。另外,AfxMessageBox()函數的參數沒有MessageBox()函數的參數豐富,所以后者較前者靈活。
AfxMessageBox不能控制消息框標題,常用於調試程序時的內部數據輸出或警告;MessageBox比較正式,常用在要提交的應用程序版本中,可以控制標題內容而不必采用含義不明的可執行文件名為標題。
cannot convert parameter 1 from 'class CLine *' to 'class CObject *'???
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
指向的類型無關;轉換要求reinterpret_cast,C樣式轉換或函數樣式轉換
There is no context in which this conversion is possible???
沒有上下文,這種轉換是可能的
二進制“=”: 沒有找到接受“int”類型的右操作數的運算符(或沒有可接受的轉換)???
error C2601: 'OnPreparePrinting' : local function definitions are illegal???
是因為你某個地方少了一個}
誰能解釋數據結構中KMP算法的next函數?
比如一個待匹配的子串str[]="abaabc",給出每個字符的next是幾,為什么?千萬別貼大段的東西,用自己的話說.
假如str的前j個字符是前i個字符的后綴(j<i),那么next[i]就是所有這樣的j的最大值
形象地說,就是假如第i+1個字符匹配失敗之后,下一個可能匹配位置至少應該往后挪動多少
就"abaabc"而言
next[1]=0
next[2]=0
next[3]=1
next[4]=1
next[5]=2
next[6]=0
計算過程基本上抄自算法導論,假設str長度為n
k=0;//k表示當前匹配了多少位
next[1]=0;
for (i=1;i<n;i++)
{
while (k && str[i]!=str[k]) k=next[k];
if (str[i]==str[k]) k++;
next[i+1]=k;
}
之后計算str和某個長度為m的字符串text匹配的過程基本上是一樣的
k=0;//用於記錄str最長能夠有前k位是text的前i+1個字符的后綴
for (i=0;i<m;i++)
{
while (k && text[i]!=str[k]) k=next[k];//發現不能匹配的時候就把str往后挪
if (text[i]==str[k]) k++;
if (k==n) printf("在位置%d處找到一個匹配\n",i+1-n);
}
data和next無法讀取內存???
例如:
datatype linkqueue::dequeue()//出隊
//若隊列不空則刪除隊列頭部元素並用x返回其值
{
datatype x;
queuenode *p = front;//p指向隊列頭結點
if (queueempty())
{
cerr << "隊列已空" << endl;
exit(1);
}
x = p->data;//運行時有中斷,原因是data和next無法讀取內存
front = p->next;//front指向新的隊列頭結點
if (rear == p) rear ==NULL;
count--;//元素個數減一
delete p;//釋放原隊列頭結點
return x;//返回原隊列結點的data值
}
其中一種修改是:
datatype linkqueue::dequeue()//出隊
//若隊列不空則刪除隊列頭部元素並用x返回其值
{
datatype x;
queuenode *p = front;//p指向隊列頭結點
if (queueempty())
{
cerr << "隊列已空" << endl;
exit(1);
}
x = p->data;//運行時有中斷,原因是data和next無法讀取內存
front = p->next;//front指向新的隊列頭結點
if (rear == p) rear =NULL;
count--;//元素個數減一
delete p;//釋放原隊列頭結點
return x;//返回原隊列結點的data值
}
心得體會:在寫程序的時候要小心,不然一點小小的錯誤就能讓你的代碼徹底崩潰。
為什么把if (rear == p) rear =NULL;寫成if (rear == p) rear ==NULL;后代碼在運行時會出現中斷???
如遞歸所有控件路徑,函數將導致運行時堆棧溢出???
MSP430程序在運行的過程中,出現死機的現象,通過IAR編譯器觀察,死機的原因是棧溢出。
因為定義的局部變量是在棧內的,所以分析可能是局部變量導致棧溢出,最有可能導致編譯器不能事先判斷
使用了多少棧的(超出設定值會報警),就是程序中產生新的占用棧的變量,由之前的經驗推測是數組越界,因為如果程序不顧數組的邊界,越界不斷的往里填東西,越界的部分就會被當成局部變量,占用棧的內存。
因為棧是從RAM的底部網上長(存數據)的,而其他程序運行的數據是從頂部往下的,所以當棧越存越多,越積越高的時候,棧就會和程序運行時的數據碰頭,二者占滿整個RAM內存,此時棧再繼續消耗,棧再向上長,直接覆蓋掉程序運行時所需的變量,程序就要跑飛了。
下面就詳細介紹如何查看ram使用情況:
1 當然是燒程序到目標板里呀
2 選擇view/memory,打開memory窗口
3 從ram的起始地址0x1C00h開始,輸入0x3fff(16KB),再回車
4 選中0x1C00h~0x005BFFh區域,右鍵選擇memory fill……
5 在memory fill中的start寫入:0x1C00h,length寫:0x3fff,value填入FF(也可填入其他值),被選中的區域全填充FF
6 運行程序,跑一遍設計的所有功能,再停止cspy,看看memory窗口
7 如果再填充的區域內已經沒有FF存在,就說明已經發生堆棧溢出或是會有溢出的危險(ram剛好夠用)。最好保留一定余量的ram不被改變,以防發生溢出
'AfxMessageBox' : no overloaded function takes 0 parameters???
c++編程中出現no overloaded function takes 3 parameters是什么意思???
意思就是說重載函數不能重載3個參數。
所以說,你就應該看看student的構造函數的參數是否帶默認的三個。
error C2374: 'i' : redefinition; multiple initialization 重定義
'HDC' : illegal use of this type as an expression
“xxxxx”: 將此類型用作表達式非法”
C++程序出現這樣的Debug Assertion Failed錯誤是什么意思怎么解決???
錯誤很顯然,vector下標超出范圍了了
調試一下,看哪個vector變量的index超出其size了
如果是errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );的話,那么
將
fp = fopen_s ("car.txt", "r");
修改為:
fopen_s (&fp, "car.txt", "r");即可。
