1 C++基础(1- 开始、变量和基本类型)

1 配置C++和基础

1.1配置C++编译环境

1.1.1利用Visual studio创建C++程序

Step1:新建项目选择win32项目
在这里插入图片描述
Step2:在win32项目选项里,将windows应用程序改成控制台程序再勾选空项目

在这里插入图片描述

Step3:在项目栏右侧添加.h或者.cpp文件。

1.1.2利用VScode创建C++程序

step1:下载MinGW

链接:https://pan.baidu.com/s/1LnO_3_N8Uw_mB87spqSBqQ
提取码:ikbf
复制这段内容后打开百度网盘手机App,操作更方便哦

step2:将压缩包解压到指定文件夹,例如D盘
Step3:打开系统高级设置,将之前解压的MinGW的bin目录添加进用户变量的path系统变量的path
在这里插入图片描述Step4:win+r打开对话框输入cmd,在命令行窗口输入g++ -v查看编辑器是否配置完成
在这里插入图片描述Step5:打开VScode 在扩展里添加C++,code runner,include autocomplete插件,添加完成后重启VScode
在这里插入图片描述Step6:新建项目,ctrl+F5进入调试,选择C++ (GDB/LLDB),然后选择g++ .exe即可。如果这步没有弹出选择g++ .exe操作则是VScode没有打开你新建的cpp文件的目录,右侧选择目录来打开即可。(因为要指定目录生成exe文件)
在这里插入图片描述

Tips:VScode每次编译C++总会生产.exe文件在.cpp文件下面,怎么把.exe文件集中到一个文件夹呢?
1、打开设置搜索code-runner:Executor Map,选择在settings.json中编辑在这里插入图片描述
2、在settings.json中的C和C++内容添加要放置的文件夹目录如D:\\Workspace\\Cpp\\build\\
在这里插入图片描述

1.2关键知识点

“()”运算符-----调用运算符。跟随在函数名之后的一对括号“()",起到调用函数的效果。传递给函数的实参放置在括号内。

“.”运算符-----点运算符。左侧运算对象必须是一个类类型对象,右侧运算对象必须是此对象的一个成员的名字。运算结果即为该对象的这个成员。

“<<”运算法----- 输出运算符,将右侧运算对象的值写到左侧运算对象表示的输出流: cout << "hi"表示将hi写到标准输出。输出运算符可以连接: cout < <“hi” << "bye"表示将输出hibye.

“>>”运算符----- 输入运算符,从右侧运算对象的值写到左侧运算对象表示的输出流: cout << "hi"表示将hi写到标准输出。输出运算符可以连接: cout < <“hi” << "bye"表示将输出hibye.

1.3练习题

1.3.1书店程序

// --------------------------Sales_item.h-------------------------------
#ifndef SALESITEM_H

#define SALESITEM_H

#include <iostream>
#include <string>
 
class Sales_item {
	friend std::istream& operator>>(std::istream&, Sales_item&);
	friend std::ostream& operator<<(std::ostream&, const Sales_item&);
	friend bool operator<(const Sales_item&, const Sales_item&);
	friend bool
		operator==(const Sales_item&, const Sales_item&);
public:

#if defined(IN_CLASS_INITS) && defined(DEFAULT_FCNS)
	Sales_item() = default;
#else
	Sales_item() : units_sold(0), revenue(0.0) { }
#endif
	Sales_item(const std::string &book) :
		bookNo(book), units_sold(0), revenue(0.0) { }
	Sales_item(std::istream &is) { is >> *this; }
public:

	Sales_item& operator+=(const Sales_item&);
 
	std::string isbn() const { return bookNo; }
	double avg_price() const;

private:
	std::string bookNo; 
#ifdef IN_CLASS_INITS
	unsigned units_sold = 0; 
	double revenue = 0.0;
#else
	unsigned units_sold;
	double revenue;
#endif
};

inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs)
{
	return lhs.isbn() == rhs.isbn();
}

Sales_item operator+(const Sales_item&, const Sales_item&);
 
inline bool
operator==(const Sales_item &lhs, const Sales_item &rhs)
{

	return lhs.units_sold == rhs.units_sold &&
		lhs.revenue == rhs.revenue &&
		lhs.isbn() == rhs.isbn();
}
 
inline bool
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
	return !(lhs == rhs);
}

Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}
 

Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
	Sales_item ret(lhs);
	ret += rhs; 
	return ret; 
}
 
std::istream&
operator>>(std::istream& in, Sales_item& s)
{
	double price;
	in >> s.bookNo >> s.units_sold >> price;

	if (in)
		s.revenue = s.units_sold * price;
	else
		s = Sales_item();
	return in;
}
 
std::ostream&
operator<<(std::ostream& out, const Sales_item& s)
{
	out << s.isbn() << " " << s.units_sold << " "
		<< s.revenue << " " << s.avg_price();
	return out;
}
 
double Sales_item::avg_price() const
{
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}
#endif

// --------------------chapter1.cpp----------------
#include<iostream>
#include"Sales_item.h"
 
int main(){
    Sales_item total;
    if(std::cin>>total){
        Sales_item trans;
        while(std::cin>>trans){
            if(total.isbn()==trans.isbn())
                total+=trans;
            else{
                std::cout<<total<<std::endl;
                total=trans;
            }
        }
        std::cout<<total<<std::endl;
    }else{
        std::cerr<<"no data"<<std::endl;
        return -1;
    }
    return 0;
}

输出结果:
在这里插入图片描述

1.3.2 程序流程图

在这里插入图片描述

2 变量和基本类型

2.1字和字节

1、比特(bit):计算机以比特序列存储数据,每个比特非0即1。

2、字节(byte):大多数计算机以2的整数次幂个比特作为块来处理内存,可寻址的最小内存块称为字节

3、字(word):存储的基本单元称为字,它通常由几个字节组成。
一般计算机的字节由8比特构成,而一个字通常为4个字节或者8个字节。
在这里插入图片描述

2.2引用(左值引用)

1、引用即是为对象起了别名;

2、引用必须初始化,而且引用的初始值必须是一个 对象

什么是对象?
通常而言对象是一块能存储数据并具有某种类型的内存空间。一些人把命名的对象和未命名的对象区分开来,他们把命名了的对象叫做变量。还有一些人把对象和值区分开来,其中对象指能被程序修改的数据,而值(value)指只读的数据。

int &a = 3  //错误

3、引用本身不是一个对象,所以不能定义引用的引用;

4、允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号&开头

关键点:对引用变量的操作就是对它所引用的那个对象的操作!!所以在某些函数的形参常常为引用类型。

2.3指针

1、了解指针,需了解 * 符号和&符号,* 可以用于定义指针,也可以用于解引用,&表示为取地址。

2、空指针不指向任何对象。int *p=nullptr定义空指针。

3、void*指针可以存放任意对象的地址,可以比较大小,因无类型,仅操作内存空间,对所存对象无法访问即不能解引用,不能强制偏移,能通过强制类型装换static_cast装换成其他类型指针。 void *指针变量主要用于将不同类型的指针变量传递给函数,在函数内部再将它强制转换为特定的指针类型。

4、指向指针的指针,指针变量p也是占据独立内存块的变量,它本身的地址也可以保存在一个 指针变量中,这个指针变量通常称为指向指针的指针,代表**符号。

5、指向指针的引用,引用本身不是一个对象,因此不能定义指向引用的指针。但指针是对象,所以存在对指针的引用,*&符号,从右向左看。

int i=42;
int *p;
int *&r = p;  //从右向左看,指针类型的引用

r = &i;  //成立,相对于p = &i

引用和指针的比较:
引用变量只是其他变量的别名,无独立内存,同一个引用变量不能修改去引用不同的变量。指针变量存储其他变量的地址,有独立内存,在不同时刻可指向不同对象。

2.4const修饰符

1、const希望定义一些不能被改变值的变量

2、const对象必须初始化,且不能被改变。

3、const变量默认不能被其他文件访问,非要访问,必须在指定const定义之前加extern。要想在多个文件中使用const变量共享,定义和声明都加const关键字即可。

4、const和指针,包括指向常量的指针指针类型的常量

5、指向常量的指针(pointer to const),不能用于改变其所指对象的值, 其定义方式有两种,以整形常量为例子,定义包括int const* p = &iconst int* p = &i。都表示指针指向的对象是常量,被指对象是不能被修改类型的。

5、指针类型的常量也叫常量指针(const pointer),指针本身是常量,定义方式有int *const p = &i;,即指针是常量类型的,也就是说指针固定指向该对象,存放在指针中的地址不变,但地址所对应的那个对象值可以修改的。

6、const和引用,即对常量的引用(reference to const),指向const对象的引用,如 const int i =1; const int &r = i;,可以读取但不能修改变量r。

临时量(temporary)对象:当编译器需要一个空间来暂存表达式的求值结果时,临时创建的一个未命名的对象。对临时量的引用是非法行为。

2.5类型别名typedef

1、类型别名(type alias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。

2、传统定义方式,使用关键字typedef,如typedef Sales_item SI

2、C++11 新特性定义,using SI = Sales_item

3、理解指针类型的typedef的不同点:这一符合类型的对象,不能代回原式来进行理解如:

typedef char *pstring;  // pstring是char*的别名
const pstring cstr = 0; // 的指针类型的常量,指向char类型
const pstring *ps;  //此时ps是一个指向char类型常量的指针
// 如改写为const char *cstr = 0;不正确,为指向const char的指针

// 辅助理解(可代回后加括号)
// const pstring cstr = 0;代回后const (char *) cstr = 0;
// const char *cstr = 0;即为(const char *) cstr = 0;

再次注意:
1、指向常量的指针定义方式const int* p = &i或者int const* p = &i,
2、指针类型的常量定义为int const* p = &i,
3、如果使用typedef的话,cons修饰的表示指针类型的常量,即const pstring p是指针类型的常量,而const pstring *p是指向常量的指针。

3字符串、容器和数组

3.1 字符串string

标准库类型string表示可变长的字符序列,注意,其不同于字符串字面值

Tips:字符串string不同于字符串字面值的例子:例如在字符串拼接(+)时候s1+s2使用时,保证至少一侧是string类型。string s1 = "hello" + "world" // 错误,两侧均为字符串字面值,不能实现字符串的拼接!!!

3.1.1 字符串string的一些操作

1、初始化:

方式一:拷贝初始化(copy initialization):使用等号=将一个已有的对象拷贝到正在创建的对象。例如string str1 = str2或者string str = "1234"等。
方式二:直接初始化(direct initialization):通过括号给对象赋值。例如string str(s1)或者string str("value")等。

    string str2 = "i_am_second";
    string str2a = str2;
    str2a[0] = 'h';

    string str2b = "i_am_test";
    string str2c = " ";
    str2b = str2c;

    cout<<"------------The using of = in string--------------"<<endl;
    cout<<"str2 is:  "<<str2<<endl<<"str2a is:  "<<str2a<<endl;
    cout<<"str2b is:  "<<str2b<<endl<<"str2c is:  "<<str2c<<endl<<endl;

输出结果为:------------The using of = in string--------------
str2 is: i_am_second
str2a is: h_am_second
str2b is:
str2c is:

2、求长度: 采用str.size()或者str.length()。

    string str1 = "i_am_first";

    // string类型的长度;(采用str.size()或者str.length())
    int len  = str1.size();cout<<"the size of str1 is:  "<<len<<endl;
    int leng = str1.length();cout<<"the length of str1 is:  "<<leng<<endl<<endl;

输出结果为:the size of str1 is: 10和the length of str1 is: 10。

3、字符串拼接: 直接通过运算符+,值得注意,+号的两个对象必须至少一个是string类型的。

    cout<<"------------The using of + in string--------------"<<endl;
    string str3 = "i_am_";
    string str3a = "third";
    string str3b = str3 + str3a ;
    cout<<"str3 is:  "<<str3<<endl<<"str3a is:  "<<str3a<<endl<<"str3b is:  "<<str3b<<endl<<endl;

输出结果为:------------The using of + in string--------------
str3 is: i_am_
str3a is: third
str3b is: i_am_third

4、字符串切片: substr(位置,长度)

    string str4 = "i_am_forth";
    string str4a = str4.substr(5,5);
    cout<<"------------slice of string type--------------"<<endl;
    cout<<"str4 is:  "<<str4<<endl<<"str4a is:  "<<str4a<<endl<<endl;

输出结果为:------------slice of string type--------------
str4 is: i_am_forth
str4a is: forth

5、其他操作:

在这里插入图片描述

3.1.2 对string对象中的字符操作

在这里插入图片描述

/*    
//----------------------------处理string中的字符--------------------------
*/
    string str5 = "I_a m _5(fifth)";

    // 判断字符是否为数字
    bool isnum = isdigit(str5[7]);
    cout<<"------------Process the characters of the string--------------"<<endl;
    cout<<"5 in str5 is digit(1=true,0=false):  "<<isnum<<endl;

    // 判断字符是否为字母
    bool isalp = isalpha(str5[1]);
    cout<<"i in str5 is alpha(1=true,0=false):  "<<isalp<<endl;

    // 判断字符是否为大写
    bool isup = isupper(str5[0]);
    cout<<"i in str5 is alpha(1=true,0=false):  "<<isup<<endl;

    // 判断字符是否为小写
    bool islo = islower(str5[2]);
    cout<<"i in str5 is alpha(1=true,0=false):  "<<islo<<endl;

    // 判断字符是否为空格等其他符号
    bool isspa = isspace(str5[3]);
    cout<<"i in str5 is alpha(1=true,0=false):  "<<isspa<<endl;

输出结果为:------------Process the characters of the string--------------
5 in str5 is digit(1=true,0=false): 1
i in str5 is alpha(1=true,0=false): 0
i in str5 is alpha(1=true,0=false): 1
i in str5 is alpha(1=true,0=false): 1
i in str5 is alpha(1=true,0=false): 1

3.1.3 例子

例子1:将字符串str5a的字符串中空格全部删除,如str5 = “i am str5a”;最后输出"iamstr5"

解题思路:
1、按下标i判断,
2、记录空格下标i,将其拆分成前后两字符(0–i和i+1–end)串再合并;
3、空格处下标再下次遍历重置为(i-1)

    for(int i = 0; i < str5a.size(); i++)
    {
        if(isspace(str5a[i]))
        {
            string str5b = str5a.substr(0,i);
            string str5c = str5a.substr(i+1);
            str5a = str5b + str5c;
            i--;
        }
    }
    cout<<"Example1--to delet the space in (i am str5a):  "<<str5a<<endl<<endl;

输出结果为:Example1–to delet the space in (i am str5a): iamstr5a

3.2 容器vector和迭代器

3.2.1 容器

1、初始化: 值得注意的是,容器的元素长度可以不一样vector<string> str = {"1","12","123"};

在这里插入图片描述

    //定义初始化,可以定义不同长度的元素在一个容器中
    vector<string> str1 = {"1","12","123"};
    cout<<"---------------to init the vector type data--------------"<<endl;
    cout<<"str1={a,ab,abc} the str[1] is:  "<<str1[1]<<endl<<endl;

输出结果为---------------to init the vector type data--------------
str1={1,12,123} the 1 number is: 12

2、添加元素: v.push_back(e) 在尾部增加元素。

    // 向末尾添加元素
    str1.push_back("1234");
    cout<<"---------------add data in the end of vector --------------"<<endl;
    cout<<"str1={1,12,123,1234} the str1[3] is:  "<<str1[3]<<endl<<endl;

输出结果为---------------add data in the end of vector --------------
str1={1,12,123,1234} the 3 number is: 1234

3、其他操作:
在这里插入图片描述

注意:vector对象(以及string对象)的下标运算符[i],只能对确知已存在的元素执行下标操作,不能用于添加元素。 以下两种情况都是错误的!!!

    string a = "";
    vector<int> b;

    for(int i = 0; i < 2; i++)
    {
        a[i] = char(i);
    }
    for(int i = 0; i < 2; i++)
    {
        b[i] = i;
    }

3.2.2 迭代器

1、获取头尾元素: 头元素 直接*str.begin()即可;尾元素需要将尾迭代器向后移动一位,否则传递出来的是空指针,即尾元素*--str.end()

    // 获取迭代器首尾元素;尾部元素需要用*--str.end(),直接得到的*str.end()一般是个空指针
    string str2 = "hello_iterator";
    vector<string> str3 = {"abc","ab","a"};
    auto str2a = str2.begin();

    cout<<"-----------get the begin and end mumber in vector and string ----------"<<endl;
    cout<<"the str2={hello_iterator} first number is:  "<<*str2a<<endl;

    auto str3a = str3.end();

    cout<<"the str3={abc,ab,a} end number[*--str3.end()] is:  "<<*--str3a<<endl<<endl;

输出结果为:-----------get the begin and end mumber in vector and string ----------
the str2={hello_iterator} first number is: h
the str3={abc,ab,a} end number[*–str3.end()] is: a

2、获取容器内数据: 例如在vector<string> str = {"abc","ab","a"};iter = str.begin()注意*iter[2](*iter)[2]的区别,前者*iter[2]==str[0+2];后者(*iter)[2]==str[0][2]

    // 对迭代指针的一些操作
    // 获取字符串内元素
    auto str3b = str3.begin();
    cout<<"-----------get the data in iterator ----------"<<endl;
    cout<<"in str3={abc,ab,a} the str3c is:  "<<*str3b<<endl;
    cout<<"in str3={abc,ab,a} the str3c[1] is(==str3[2]):  "<<str3b[2]<<endl;
    cout<<"in str3c={abc} the (*str3c)[2] is(==str3[0][2]):  "<<(*str3b)[2]<<endl;

输出结果为:-----------get the data in iterator ----------
in str3={abc,ab,a} the str3c is: abc
in str3={abc,ab,a} the str3c[1] is(==str3[2]): a
in str3c={abc} the (*str3c)[2] is(==str3[0][2]): c

3、其他操作:

在这里插入图片描述

3.3数组

1、数组的长度长度必须是const表达式,或者不写。

2、数组不允许直接赋值给另一个数组。

int a[] = {1,2,3};
int b[] = a; //错误
int c[];
c = a;//错误

3.3.1复杂数组

1、指针类型的数组(指针数组),关键字<type>* <var_name>,例如int *arrp[10],表示10个int* 类型的指针数组。

2、指向数组的指针(数组指针),关键字<type> (*<var_name>),例如int (*parr)[10]表示指向10个整形数组的指针。

运算符优先级:赋值运算符<逻辑运算符<关系运算符<算术运算符<括号

int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *arrp[10];  //int类型指针的数组
int (*parr)[10];    //指向10个整形元素的数组的指针
// arrp = &arr; //错误!
parr = &arr;
cout<<parr<<endl;   //输出数组首地址
cout<<parr[0]<<endl;   //输出数组首地址
cout<<*parr[2]<<endl;   //并非输出数组的值,而是数组的地址的十进制数,做法完全不推荐
cout<<(*parr)[2]<<endl;   //输出数组的值

3、数组的引用,关键字<type> (&<var_name>),例如int (&refarr)[10] = arr表示10个整形数组的引用。不能定义数据类型是引用的数组。

3.3.2 C风格字符串

1、从C继承来的字符串,用空字符(\0)结束。

2、相关操作:
strlen(p) ------返回p的长度,空字符不计算在内;

strcmp(p1, p2)------比较p1和p2的相等性。如果p1==p2,返回0;如果p1>p2,返回一个正值;如果p1<p2,返回一个负值;

strcat(p1, p2)------将p2附加到p1之后,返回p1;

strcpy(p1, p2)------将p2拷贝给p1,返回p1。

3.3.3 数组和指针

arr[j] == *(&arr[0]+j) == *(arr+j) == *(j+arr) == j[arr]

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值