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" ([email protected]@@[email protected]@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");即可。