学习C++的笔记(算法与数据结构要求(2)(我不是黑瞎子掰棒子

本文总结了C++编程中常见的错误,包括函数声明与定义不匹配、指针操作、字符串定义、文件读取、容器操作、模板使用、类型转换等方面,并提供了相应的解决方案。同时,讲解了类模板、栈、队列、链表、哈希表等数据结构的使用技巧。此外,还涉及了运算符重载、内存管理以及错误处理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

debug的故事

class里的函数的声明和初始化,括号里的参数的表示名字得一致,否则就会识别成两个函数(在类外定义的时候)

void init(int yy,int mm,int dd);
void Date::init(int yy,int mm,int dd)

函数语句解读

1.指向class里的函数的指针

void(Date::*p3)(int,int,int);
p3=Date::init;   //别加括号,以及参数
(date1.*p3)(2006,4,8);//取出对应的函数的名称,指针取出的名称

特殊的语句格式。

2.字符串的定义用中括号 char name[3] ;

3.cout'<<\t'=TAB,就是空格

4.指针的浅拷贝

p1=new Person;
p2=new Person;
*p2=*p1;

这个居然是浅拷贝,有售后的复制粘贴,震惊我

浅拷贝居然是有售后的拷贝

5.this指针

这仨结果一样,x是private。

cout<<x;
cout<<this->x;
cout(*this).x;

6.vector.size()

vector自带的size工具是 vector.size()。别忘了括号

7.[Warning] unknown escape sequence: '\F'

 正则表达式是字符串引擎,C++中"\“在字符串中表示要用”\\"

 8.c++读取文件代码

#include <vector> 
#include <string> 
#include <fstream> //读取文件专门添加的
#include <iostream> 
using namespace std; 
int main() 
{
	int i;
	ifstream ifs;
	ifs.open("E:\\File of chedui\\2021\\22\\fig01_02.cpp",ios::in);//打开文件
	if (!ifs.is_open()) {
		cout << "文件打开失败" << endl;
	}
	vector<string> vStr;
	string buff;                          //把文件内容读取到string里
	while (getline(ifs, buff))            //在加到vector里
	    {
			vStr.push_back(buff);
		} ;
	for(int i=0;i<vStr.size();++i)        //作用是输出vector,别忘了()
		{
			cout << vStr[i]<< endl;
		};
	
	ifs.close();
	system("pause");
}

9.vector和stack

vector添加元素是push_back(i)

stack添加元素是push(i)

括号里是要添加的元素

10.看了c和c++的栈的区别,我只想大吼一声c++yyds

11.unexpected token '{' following declaration of 'main'

int main ()

后面忘记加()了

12.别忘了using namespace std;

13.pop是删除栈顶的东西,用法是"栈名.pop()"

括号里本来就是空的

14.devc++确实不支持stack,我也不知道咋调

15.c== '/'||c=='*'||c=='('||c=='['||c=='{'每个都要有“c==”

16.redefinition of default parameter


int add(int m, int n =10);
int main()
{};
int add(int m, int n)//如果这个地方加上int n=10就会报错
{
return (m + n);
}

17.undeclared identifier nullptr

化nullptr为NULL就ok

18.vector.end();

这个像是老虎的尾巴,摸不得,返回值是-1,赋值最往后赋值到倒数第二个。

在指针指到end-1之后,下一个就再回到开头,别指到end,否则返回值是-1

(1条消息) vector.end()指向的是最后一个元素的下一个位置,所以访问最后一个元素的正确操作为:vector.end() - 1;_hzw.000的博客-CSDN博客

19.list的尾巴

list的尾巴即list.end()也是这样

不能输出,不能调用,只在指针指到倒数第二个的时候移到第一个去。 

20.*(list/vector).(begin/end)()

得加星号,否则是输出的地址

21.返回值为struct的函数的赋值

tmp = numbers inputinformation();
//返回值为叫做numbers的结构体
//这样会报错
//[Error] expected primary-expression before 'inputinformation'
tmp = inputinformation();
//这样没问题,因为去掉了numbers

22.stack的初始化以及string的输入输出

    stack<char> num;//用stl里的stack
	stack<int> ope;
	string s;
	cout<<"请输入表达式:"<<endl;//string可以直接输入输出,用cin和cout
	cin>>s;
	cout<<s;

string一般配的是char*的指针

char *p;
p = &cal1.s[0];

class外定义函数,:函数类型 class名字::函数名称

class定义的时候,后面没有小括号

class date ()这里没有小括号

int n=cal1.s.length();//判断遍历次数,即表达式的长度 

string的长度只能通过length获取

char类型的数字转化成int型的数字

char c='1'
int a=c-'0';//单引号哦

有时间搞明白,多个cpp文件一起工作的原理

判断stack是不是空,别用size==0.用empty()更好

c++幂函数

//使用到库文件#include<cmath>
int a;
a=(int)pow(2.2,3);
cout<<a;

compare(int a,int b)

比较 a,b数值的大小  a>b  返回值为 1

                               a=b 返回值为 0 

                                a<b 返回值为 -1

     ptr pa,pb,pc,pd;
	 pa=a.begin();
	 pb=b.begin();
	 pc=c.begin();
	 //pd=d.begin();
	numbers testa,testb,testc,testd;
	 testa=*pa;
	 testb=*pb;
	 testc=*pc;

这样的话,如果pa移动,testa是不会变的哦,得移动之后再赋值一次。

vector和list的区别,分清楚

C++ vector和list的区别 - 迪米特 - 博客园 (cnblogs.com)

 队列(queue)和栈(stack)是list的特殊情况。

[数据结构]——链表(list)、队列(queue)和栈(stack) - eudiwffe - 博客园 (cnblogs.com)

list 的list的end里没有东西,最后的数值在end()-1里,

插一嘴,我想用matlab算二元二次方程组的解

syms t m;

eq1 = 3.25*3.25+m^2-t^2-2*m*3.25*cos(88.37)==0;
eq2 =(m^2+t^2-3.25*3.25)*(2*(9.38-t)*(9.09-m))-2*m*t*((9.38-t)^2+(9.09-m)^2-6.75*6.75)==0;

[t, m] = solve(eq1, eq2, t, m);
%disp(t);
disp(m);

 这样不对,答案不对

struct的构造函数

这是很有用的,不过我还没有太学会。 

不太明白

template <class T>

template <class T> // 最常用的:一个class 参数。

template <class T, class U> // 两个class 参数。

template <class T, int N> // 一个class 和一个整数。

template <class T = char> // 有一个默认值。

template <int Tfunc (int)> // 参数为一个函数。

这是建立模板的固定形式,template即模板,class指类别,T是类别的统称,可以使用的数据类型有int、char,float,double等等。

template < typename T >
T min( T a, T b )
{
return a > b ? b : a;
}

在模板定义语法中关键字class与typename的作用全然一样。这里class关键字表明T是一个类型。

类模板(也称为类属类或类生成类)同意用户为类定义一种模式。使得类中的某些数据成员、默写成员函数的參数、某些成员函数的返回值,能够取随意类型(包含系统提前定义的和用户自己定义的)。

当中通用类型T能够作为普通成员变量的类型,还能够作为const和static成员变量以及成员函数的參数和返回类型之用。

在类定义体外定义成员函数时,若此成员函数中有模板參数存在,则除了须要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明

C++中 模板Template的使用 - cynchanpin - 博客园 (cnblogs.com)

这个写的很清楚 

假设函数是以通用类型为返回类型,则要在函数名前的类名后缀上“<T>”。

const T&

对常量(const)的引用,又称为常量引用,常量引用不能修改其邦定的对象。

bool Insert(const T& key)

(2条消息) const T、const T*、T *const、const T&、const T*& 的区别_luoweifu的博客-CSDN博客_const*

这个讲的很明白 

void和bool的区别

C++是强类型的语言,“void”是返回类型,但是它是无返回值的返回类型;“bool”是有返回值的返回类型,但是它的返回值只有两个,分别是“true”和“false”。

while(pointer)

意思是,如果指针非空,就一直执行

产生随机数

srand(time(NULL));//注意头函数以及time的括号里得有东西
1.Insert(rand()%100 + 1);
//注意循环只能循环最后一句,别把第一句也循环 了,否则生成一串同一个数字
//这样才可以哦
srand(time(NULL));
	for (int i = 0; i < p; i++)
	{
		T1.Insert(rand()%100 + 1);
	}

 struct的构造函数,不要定义空的参数,所以加上一个构造函数

struct BSTNode
{
	T val;
	BSTNode<T>* Nodeleft;
	BSTNode<T>* Noderight;
	BSTNode(const T m) { val = m; Nodeleft = NULL; Noderight = NULL; };
	BSTNode() { val = 0; Nodeleft = NULL; Noderight = NULL; };
};

(2条消息) c++ 定义对象数组报错no matching function for call to_cjh_hit的博客-CSDN博客

要不会报错的,就想上面那个

#include<stdio.h>
#include<string.h>
#define MAX_HASH_TABLE_LEN 10
#define true 1
#define false 0
typedef int  bool;

typedef struct _NODE
{
    int data;
    struct _NODE* next;
}NODE;

typedef struct _HASH_TABLE
{
    NODE* value[MAX_HASH_TABLE_LEN];
}HASH_TABLE;


/*哈希表索引 _创建hash表()*/
HASH_TABLE* create_hash_table()
{
    return (HASH_TABLE*)calloc(1, sizeof(HASH_TABLE));
}


/*数据所在的节点 _hash表当中寻找数据(哈希表索引,目标数据)*/
NODE* find_data_in_hash(HASH_TABLE* hashtable_index, int data)
{

    if (NULL == hashtable_index)
        return NULL;

    NODE* node_index = NULL;
    if (NULL == (node_index = hashtable_index->value[data % MAX_HASH_TABLE_LEN]))
        return NULL;

    while (node_index) {
        if (data == node_index->data)
            return node_index;
        node_index = node_index->next;
    }
    return NULL;
}

/*成败 _在hash表当中插入数据(哈希表索引,目标数据)*/
bool insert_data_into_hash(HASH_TABLE* hashtable_index, int data)
{   
    if (NULL == hashtable_index)
        return false;

    NODE* node_index = NULL;
    if (NULL == hashtable_index->value[data % MAX_HASH_TABLE_LEN]) /*主键table位为空*/
    {
        node_index = (NODE*)calloc(1, sizeof(NODE));        
        node_index->data = data;
        hashtable_index->value[data % MAX_HASH_TABLE_LEN] = node_index;
        return true;
    }

    if (find_data_in_hash(hashtable_index, data))/*有相同的data则不插入*/
        return false;

    node_index = hashtable_index->value[data % MAX_HASH_TABLE_LEN];
    while (node_index->next)
        node_index = node_index->next;
    node_index->next = (NODE*)calloc(1, sizeof(NODE));
    node_index->next->data = data;
    return true;
}

/*成败 _从hash表中删除数据(哈希表索引,目标数据)*/
bool delete_data_from_hash(HASH_TABLE* hashtable_index, int data)
{

    NODE* node_index = NULL;
    if (NULL == hashtable_index || NULL == hashtable_index->value[data % MAX_HASH_TABLE_LEN])
        return false;

    if (NULL == (node_index = find_data_in_hash(hashtable_index, data)))
        return false;

    if (node_index == hashtable_index->value[data % MAX_HASH_TABLE_LEN]) {
        hashtable_index->value[data % MAX_HASH_TABLE_LEN] = node_index->next;
        goto final;
    }

    NODE* first_node_index = hashtable_index->value[data % MAX_HASH_TABLE_LEN];
    while (node_index != first_node_index->next)
        first_node_index = first_node_index->next;
    first_node_index->next = node_index->next;

    final:
    free(node_index);
    return true;
}

/*遍历打印哈希表(哈希表索引)*/
void print_hash(HASH_TABLE* hashtable_index)
{
	int i = 0;
    if (NULL == hashtable_index) 
        return;

    for (i = 0; i < MAX_HASH_TABLE_LEN; ++i)
    {
        NODE* tmp = hashtable_index->value[i];
        while (tmp)
        {
            printf("%d-", tmp->data);
            tmp = tmp->next;
        }
        printf("\n");
    }
}

int main()
{
	int i = 0;
    HASH_TABLE* h = create_hash_table();

    for (i = 0; i < 100; ++i)
    {
        insert_data_into_hash(h, i);
    }
    printf("打印哈希表:\n");
    print_hash(h);

    printf("查找哈希表中data=10元素 : \n"); 
    printf("%d\n", (find_data_in_hash(h, 10))->data);

    printf("删除data=99元素:\n");
    delete_data_from_hash(h, 99);

    printf("打印哈希表:\n");
    print_hash(h);

    system("pause");
    return 0;
}

取余取模

取模运算(“Modulus Operation”)和取余运算(“Remainder Operation ”)两个概念有重叠的部分但又不完全一致。主要的区别在于对负整数进行除法运算时操作不同。取模主要是用于计算机术语中。取余则更多是数学概念。

[Error] expected unqualified-id at end of input

这个是指的{}等符号不成对

【C++】array和vector,数组三者区别和联系

结论:能用vector就用vector;

was corrupted

关于报错:Run-Time Check Failure #2 - Stack around the variable 'xxx' was corrupted的解决方式_Adam Xi的博客-CSDN博客

运算符重载& operator=

返回值是class的类型的名字,&是返回值引用

就是,加上可以连等也可以实现数组,而且返回const引用效率最高

连通分量:不连通的图是由2个或者2个以上的连通子图组成的。这些不相交的连通子图称为图的连通分量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值