本文是针对我个人对于c++的薄弱点做的笔记,文中出现了错误希望大家能够理解,并且指出。
1.变量类型
int:取值范围:
−
2
31
-2^{31}
−231~
2
31
−
1
2^{31}-1
231−1
大致范围:
−
2
×
1
0
9
-2\times10^{9}
−2×109~
2
×
1
0
9
2\times10^{9}
2×109
2.转义字符
/0代表空字符NULL,其ASCII码为0。
3.符号常量和const常量
#define pi 3.14
const doubloe pi = 3.14;
推荐使用const
#include<cstdio>
#define cal(x) (x * 2 + 1)
int main(){
int a = 1;
printf("%d",cal(a + 1));
}
输出结果:4
注意:为什么不是5,因为宏定义只是将替换的部分原封不动替换,导致cal(a + 1)实际上是(a + 1 * 2 + 1) = 5;
#define cal(x) ((x) * 2 + 1)) //正确
4.赋值表达式
n /= m + 1;等价于 n = n / (m + 1);
5.scanf函数的使用
scanf("格式控制",变量地址);
scanf("%c",&c);
scanf("%s",str);//数组名称本身就代表这个数组第一个元素的地址,所以不用再加取地址符
scanf("%d:%d:%d",&hh,&mm,&ss);
注意:除%c外,scanf对其他格式符的输入是以空白符(即空格,换行)为结束标志的。
6.三种实用的输出格式
(1)%md
%md可以是不足m位的int数据以m为进行右对齐输出。如果位数超过m,则保持原样
(2)%0md
与%md唯一的不同是不足的位数用0补齐
(3)%.mf
浮点数保留m位小数输出
7.常用的math函数
fabs(double x) 取绝对值
floor(double x) ceil(double) 向上向下取整
log(double x)以自然对数为底的对数
round(double x) 四舍五入
8.switch语句
switch(表达式){
case 常量表达式 1:
......
break;
case 常量表达式 2:
......
break;
case 常量表达式 3:
......
break;
default:
......
}
9.数组的赋值
int a[10];//数组元素的值是随机数
int a[10] = {1,2,3};//后面没有赋值的元素默认为零
给数组元素赋值为零可以这样做:
int a[10] = {0};
int a[10] = {};
开辟的数组大小较大需要定义在主函数外面,因为函数内部申请的局部变量来自于栈,允许申请的空间小,函数外申请的全局变量来自于静态存储区,允许申请的空间较大,
10.memset–对数组中每一个元素赋相同的值
memset(a,-1,sizeof(a))//注意只能赋值-1和0
因为memset、是按照字节赋值的而-1和0的补码都是全零和全1
若要赋值其他数值可以用fill(a,a+n,1);
fill函数它的原理是把那一块单元赋成指定的值;
11.strcmp strcpy strcat函数
strcmp:按照字典序排序,前一个大于后一个返回一个整数,等于返回零,小于返回一个负数;
strcpy :字符串复制将后一个复制给前一个;
strcat:字符串拼接;
12.sscanf和sprintf函数
scanf函数可以理解成:
scanf(screen,"%d",&n);//其中screen代表屏幕
scanf的输入其实就是把screen的内容以%d的格式传输到n中,printf则是将n以%d的格式输出到屏幕;
理解这个我们就很好理解下面两个函数了
sstring只是将screen换成了字符数组
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
char str[10] = "123";
sscanf(str,"%d",&n);
printf("%d",n);
}
输出结果:
123
#include<bits/stdc++.h>
using namespace std;
int main(){
int n = 12;
char str[10];
sprintf(str,"%d",n);
printf("%s",str);
}
输出结果:
12
13.以数组作为函数参数
数组作为参数时,在函数中对数组元素的修改就等同于是对原数组元素的修改,因为数组名就是该数组的首地址。
不过虽然数组可以作为参数,但是却不允许作为返回类型出现,如果要返回数组,则只能将想要返回的数组作为参数传入。
14.指针
1.指针是一个unsigned类型的整数
2.指针变量的定义
int *p;//int* 才是类型p是变量名
注意:
int* p1,p2;//p1是指针变量,p2是int变量
int* p1,*p2;
a + i 等价于 &a[i];
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10];
for(int i = 0; i < 10; i++) scanf("%d",a + i);
for(int i = 0; i < 10; i++) printf("%d",*(a + i));
}
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10] = {1,2,3,4,5};
int *p = a;
int *q = &a[2];
printf("%d\n",p);
printf("%d\n",q);
printf("%d",q - p);
}
p和q的具体数值和运行环境有关,但是他们的结果一定是相差8然后根据int是4个字节,所以q-p等于8/4 = 2;
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
通过指针作为参数实现交换函数;
错误写法1:
void swap(int *a,int *b){
int *temp = *a;
*a = *b;
*b = *temp;
}
错误原因:temp没有初始化,可能指向系统工作区间
更正:
void swap(int *a,int *b){
int x;
int *temp = &x;//随机给temp一个地址
*temp = *a;
*a = *b;
*b = *temp;
}
错误写法2:
void swap(int *a,int *b){
int *temp = a;
a = b;
b = temp;
}
在函数里改变了int *a,*b的地址不能返回到main函数,因为他们是副本,是形参。
15.引用
引用的含义:给变量起了一个别名,对引用变量的操作就是对原变量的操作。
上一点中错误解法二的更正就可以用到引用了
#include<bits/stdc++.h>
using namespace std;
void swap(int * &a,int * &b){
int temp = *a;
*a = *b;
*b = temp;
}
int main(){
int a = 1, b = 2;
int *p1 = &a, *p2 = &b;
swap(p1,p2);
cout << *p1 << *p2 << endl;
}
在主函数中调用需要注意:
不能直接调用swap(&a,&b);//因为常量a,b不可以使用引用
16.结构体的使用
struct node{
node n;//错误
node *p;//指向结构体的指针变量
};
struct node{
int id;
node *next;
}n,*p;
访问结构体元素:
n.id
n.next
(*p).id
p->id
注意:.和->都是成员选择只是.前面的是对象->前面的是指针;
17.结构体的构造函数
简化写法:
node(int id):id(id){}
18.getline函数
读入一整行字符串中间有空格
string str;
getline(cin,str);