CPP基础笔记

⚓CPP基础学习

练习代码可以来 https://github.com/cher112/PAT----

🏍输入输出

📫scanf()

数组名称本身就代表了这个数组第一个元素的地址
因此 scan(“%s”,str)——字符串数组,不需要加地址符

scanf的%c格式可以读入空格和换行
%s识别空格作为字符串的结尾

实用输出格式

  • %md

使不足m位的int 以m位用空格进行右对齐输出,若超过m位则不动

  • %0md

与上个相似,不是空格而是“0”填充
在某些题很有用。

  • %.mf

让浮点数保留m位小数输出

getchar putchar

用来输入/ 输出单个字符。
注意:

  • getchar可以识别换行符
  • 可以用 getchar();进行空读,不储存

gets puts

  • gets用来输入一行字符串 识别换行符\n作为输入结束
  • puts用来输出一行字符串,将某数组的一维在界面输出,并紧跟一个换行

**
**

📜C语言标准库

C 标准库是一组 C 内置函数、常量和头文件,比如 <stdio.h>、<stdlib.h>、<math.h>,等等。这个标准库可以作为 C 程序员的参考手册。
而 STL是 C++的标准模板库。

math.h 常用math函数

  • fabs(double x)——对double变量取绝对值 return double
  • floor(double x)& ceil(double x)——double类型的 向下/向上 取整 return double
  • pow(double r,double p)——返回 r^p(double 型)
  • sqrt(double x)——返回double类算术平方根
  • sin/cos/tan(double x)——取三角函数值
  • round(double x)——对double变量四舍五入 return double型

string.h 常用str函数

  • strlen()——返回字符数组中第一个\0前字符的个数。

    一维字符数组,二维字符数组的第二位的末尾都有一个空字符\0
    表示存放的字符串的结尾
    !!注意:如果不是用scanf(%s)或者gets()输入字符串,一定要在末尾加\0,不然无法识别字符串末尾,出现乱码

  • strcmp(1,2)——返回两个字符串大小比较结果,1<2返回负整数;1==2返回0

1>2返回正整数
依照字典序

字典序:
以 a、b、c……z 的顺序排列;如果第一个字母一样,那么比较第二个、第三个乃至后面的字母。如果比到最后两个单词不一样长(比如,sigh 和 sight),那么把短者排在前。
eg: aaaa小于aab,因为到第三个字符b>a

  • strcpy(str 1,str2)

把一个字符串(包括结束符),复制给另外一个字符数组

  • strcat(str 1,str 2)

把一个字符串接到另一个后面

  • 🌟sscanf,sprintf

image.png
sscanf的s理解为str
则sscanf(str,“%d”,&n)——把str的内容读给n
ssprintf(str,“&d”,n)——把n的值打印到str

当然%d,%lf,&s也是可以的。

🍜非基本数据类型

🕵️‍♀️指针

&是取地址运算符;
int * p = &a 中,int* 是指针变量的类型,&a赋给p而不是 p *星号只是表示类型的一部分。**
printf(“%d”,p); 中,*星号视为一把开启的钥匙,引到地址对应的val 星号-》 解引用符。**
**
而 &和都是 *类型修饰符**

int p 中, int被称为*基类型**

数组名称作为 数组的首地址使用

使用指针变量作为函数参数

假如不return 值,函数内的很多地址和内容(with 作为函数参数的副本值)在函数结束后会被释放掉
经典:swap(int a,int b),假如传进去2值,只会对这两个值的副本进行操作,函数执行结束gc。

正确——在函数内 把地址内的值进行修改

c语言是按值传递,”传址”只不过是c里指定的“传输地址的unsigned int”

🎃引用

相当于给main里变量起了“别名”,而不是函数中作为局部变量的副本,不会销毁。因此不用担心局部变量销毁问题。
对引用修改就相当于给被绑定的对象修改
eg:image.png
引用不是对象

对const引用

把引用绑定到const上,对常量的引用不能用作修改被绑定的对象。
eg:
image.png

2\n 3\n 3

如果用p++; 会给出 increment of read-only reference ‘p’ 只读引用。

Struct使用

struct stuInfo{
int id;
char gender;
}stu, *p;

含义:定义一个结构体,有 id gender两个域
stu是结构体名,而p是对应的指针变量名
可以用 stu.gender || (*p).gender || p->gender 来访问域

🦐初始化
struct stuInfo{
/id 和 gender域,省略/
stuInfo(){}
stuInfo(int _id, char _gender){….对结构体变量赋值 }
}

可以用上面的访问方法来一个一个初始化,
or用构造函数来初始化。其中,只要参数个数类型不完全一样,就可以定义多个构造函数~

补充:int _id意味着 id在结构体的私有域。OOP saigao。

Q:列表初始化
A:
🎇Q:如何在C++中创建类
A:到第七章
**
Q:分离式编译——声明和定义的区别。声明加 extern 关键字有什么用
A: C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义。

变量的定义(definition)用于**为变量分配存储空间**,还可以**为变量指定初始值。**在程序中,变量有且仅有**一个**定义。
声明(declaration)用于向**程序表明变量的类型和名字**。定义也是声明:当定义变量的时候我们声明了它的类型和名字。可以通过使用extern声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern。
extern声明不是定义,也**不分配存储空间**。事实上它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。
任何在多文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义)。

image.png

处理类型

类型别名

image.png

auto

image.png

decltype

👷‍♂️STL

概念补充:容器
image.png

string容器

初始化

image.png

std::cin中, ::是作用域操作符 —— 从左侧类&命名空间的作用域中寻找“cin”的域

类和命名空间访问作用域都是用::

Q:命名空间和类区别?
A:命名空间详解

标准库的string类型不是 字符串字面值

假如遍历字符串,可以
image.png

可以使用下标[n]表示,其中image.png
image.png)image.png
Q:.size() 和 size_type类型的关系
A:
image.png
方法:
记住append()

vector容器

vector不是类&函数,是类模板,根据模板创建类的过程称为实例化

image.png
Q:C++的初始&实例化和 java的区别? java写的是不是也是类模板而不是类?
A:自我理解:类模板对各种域的类型还未规定,所以只是搭建了一个模板而不是真实的类
而class已经定了各种域和方法,无法显式改变类别。
具体内容待补充
image.png

初始化

image.png

比较喜欢用倒数第二个方法

额外方法
用迭代器一个个push
image.png

遍历

for(auto i: vector) {cout<<i<<” “;}

遍历打印vector元素,其中 i是vector的 下标索引(int类型)

二维vector

vector v(&v1[0],&v1[6]); //一维一维的写

😘迭代器

image.png
!迭代器初始化
/对于标准库类型/
auto it = s(某个标准库类型).begin();
auto it( s.begin());
/对于数组/
auto it( array[0]);
auto it(std::begin( array )) (补充,尾元素用 std::end(array_name))

⭐Q:运算符it.begin() 为什么不是函数(方法)? 或者说 begin() 和 .begin()有什么区别,为什么后面是关键字
A:api说,begin和end 是 string vector的成员,同时使STL函数,感觉是写错了。。。

注意!!!
C++11 auto
auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型,类似的关键字还有decltype。举个例子:

int a = 10;
auto au_a = a;//自动类型推断,au_a为int类型
cout << typeid(au_a).name() << endl; //typeid返回变量类型

迭代器中,用auto只是为了方便,正确的应该是
image.png

👌数组&指针

使用数组的时候,编译器一般会把他转化为指针

/*nums是个数组*/
string *p = &nums[0];
等价于:
string *p = nums

数组类型的对象其实是 指向该数组首元素的指针

指针运算

给一个指针加减一个整数,仍是指针,相比原来的前进/后退了几个位置(非机器字长,而是地址)
eg:
int *ip = arr; // &arr[0]
int * ip2 = ip+4; //指向arr[4]

指针相减,结果是两指针间的地址距离,参与运算的必须指向同一个“数组”
end(arr) - begin(arr) // return ptrdiff_t 标准库(signed)类型,类似size_t 都是机器相关类型

💽表达式 运算符

比起运算符,感觉更应该叫“操作符”

  • 成员访问运算符: 点运算符&箭头运算符
  • 位操作符(检查和设置2进制位):暂忽略。

    大多数用于 unsigned,因为符号位处理没规定。

🤕局部对象

在C++中,名字有作用域 对象有生命周期

same as java>>>

局部对象——形参和函数体内部定义的变量

自动对象

存在于块执行期间的对象,当块执行完就变为未定义。

形参也是自动对象,函数开始时 申请储存空间,函数终止即gc

局部静态对象

从第一次初始化到 程序终止才gc,即使函数结束执行也不影响


本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!