算法笔记[第二章]

变量和常量

变量名:字母数字下划线,数字不开头

强制类型转换

#include <stdio.h> //include<cstdio>c++中的写法
//(新类型名)变量名
void main() {
	double r = 12.56;
	int a = 3, b = 5;
	printf("%d\n", (int)r);
	printf("%d\n", a / b);
	printf("%.1f", (double)a / (double)b);
}
------------------------
12
0
0.6

常量和宏

宏是原封不动的将对应部分替换

#define pi 3.14
#define ADD(a,b) ((a)+(b))
void main(){
    const r = 777;
}

运算符

注意使用位运算符<<,>>时一定要使用括号,因为位运算符的优先级低

const int INF = (1 << 30) - 1;

输入输出

scanf

除了数组外都需要使用地址符&

数据类型格式符举例
int%dscanf("%d",&n);
long long%lldscanf("%lld",&n);
float%fscanf("%f",&fl);
double%lfscanf("%lf",&dbl);
char%cscanf("%c",&c);
string%sscanf("%s",str);

注意

  • double的格式符是%lf
  • %c是可以接收空格,回车等空白符的
  • 除了%c以外的都以空白符为结束
#include <stdio.h>
void main() {
	int a;
	char c, str[10];
	scanf("%d%c%s", &a, &c, str);
	printf("a=%d,c=%c,str=%s", a, c, str);
}
-------------------
input:1 a bcd
output:a=1,c= ,str=a

printf

数据类型格式符举例
int%dscanf("%d",&n);
long long%lldscanf("%lld",&n);
float%fscanf("%f",&fl);
double%fscanf("%f",&dbl);
char%cscanf("%c",&c);
string%sscanf("%s",str);

注意

  • double的格式符是%f

  • %md

    共m位,右对齐,不够m位的用 空格 填充,大于m位的不用管

    void main() {
    	int a = 123;
    	int b = 12345;
    	printf("%5d\n", a);
    	printf("%3d", b);
    }
    ------------------
      123
    12345
    
  • %0md

    共m位,右对齐,不够m位的用0填充,大于m位的不用管

    void main() {
    	int a = 123;
    	int b = 12345;
    	printf("%05d\n", a);
    	printf("%03d", b);
    }
    ------------------
    00123
    12345
    
  • %.mf

    void main() {
    	double dbl = 12.3456;
    	printf("%.0f\n", dbl);
    	printf("%.1f\n", dbl);
    	printf("%.2f\n", dbl);
    	printf("%.3f\n", dbl);
    	printf("%.4f\n", dbl);
    }
    ---------------
    12
    12.3
    12.35
    12.346
    12.3456
    
    

getchar和putchar

输入单个字符

int main() {
	char c1, c2, c3;
	c1 = getchar();
	getchar();
	c2 = getchar();
	c3 = getchar();
	putchar(c1);
	putchar(c2);
	putchar(c3);
}
--------------------
input: abcd  
output: acd 
b被getchar接收但是没有赋给变量名
c1,c2,c3分别对应acd   

gets和puts

gets识别\n作为输入结束

void  main() {
	char str1[10];
	char str2[5][10];
	gets_s(str1);//vs2019认为gets不安全,用gets_s代替
	for (int i = 0; i < 3; i++) {
		gets_s(str2[i]);
	}
	puts(str1);
	for (int i = 0; i < 3; i++) {
		puts(str2[i]);
	}
}
特别注意
  • 使用scanf和gets时末尾会自动添加\0,所以a[10]实际可用只有9位
  • 使用getchar来输入字符串的时候末尾一定要手动添加\0
  • 只有char型字符串需要添加\0,数值型数组不需要
  • puts自带回车

sscanf和sprintf

void main() {
	//字符串转数字,从字符串中扫出来
	int n;
	char str[100] = "123";
	sscanf(str, "%d", &n);
	printf("%d\n", n);
	//数字转字符串,打印到字符串中去
	int m = 233;
	char str2[100];
	sprintf(str2, "%d", m);
	printf("%s\n", str2);
}
--------------------------
123
233
进阶
void main() {
	int n;
	double db;
	char str[100] = "2048:3.14,hello", str2[100];
	sscanf(str, "%d:%lf,%s", &n, &db, str2);
	printf("n=%d,db=%.2f,str2=%s\n", n, db, str2);
}
------------------------
n=2048,db=3.14,str2=hello
========================
void main() {
	int n = 2048;
	double db = 3.14;
	char str[100] = "hello", str2[100];
	sprintf(str2, "%d:%f,%s", n, db, str);
	printf("%s\n", str2);
}
-------------------------
2048:3.140000,hello

cin和cout

C++中的输入输出函数,在头文件#include<iostream>using namespace std;才可以使用

#include<iostream>
using namespace std;
void main() {
	int n;
	double db;
	char c;
	char str[5];
	cin >> n >> db >> c >> str;
	printf("%d\n", n);
	printf("%f\n", db);
	printf("%c\n", c);
	printf("%s\n", str);
	cout << n <<"haha" << db << "haha" << c << "haha" << str;
}
--------------------------------
1 2 z abcd
1
2.000000
z
abcd
1haha2hahazhahaabcd

常用math函数

#include<math.h> //include<cmath>

double fabs(double x)

#include<math.h>
void main() {
	double n = -12.34;
	printf("%.2f", fabs(n));
}
-----------
12.34

double floor(double x)和double ceil(double x)

向下取整floor,向上取整ceil,

按照数轴看向下和向上

void main() {
	double db1 = -5.2, db2 = 5.2;
	printf("%.0f, %.0f\n", floor(db1), ceil(db1));
	printf("%.0f, %.0f\n", floor(db2), ceil(db2));
}
---------------------
-6, -5
5, 6

double pow(double r,double p)

r 的 p次方

void main() {
	double db = pow(2.0, 3.0);
	printf("%f", db);
}
----------
8.000000

sqrt(double x)

void main() {
	double db = sqrt(9.0);
	printf("%f", db);
}
---------------
3.000000

double log(double x)

计算以e为底的对数

其他底数需要使用换底公式 l o g a b = l o g e b l o g e a log_{a}{b}=\frac{log_{e}{b}}{log_{e}{a}} logab=logealogeb

void main() {
	double db = log(1);
	printf("%f", db);
}
-------------------
0.000000

sin(double x),cos(double x),tan(double x)

返回值是double型,x使用弧度表示

asin(double x),acos(double x),atan(double x)

返回值是double型,x使用弧度表示

double round(double x)

round四舍五入

不使用round时的舍入规则是:四舍六入五成双,即保证进位后的最后一位是偶数

#include<stdio.h>
#include<math.h>
int main() {
	double db1 = round(3.1);
	double db2 = round(3.5);
	double db3 = round(3.7);
	printf("%d %d %d ", (int)db1, (int)db2, (int)db3);
	return 0;
}

分支和循环

switch

不写break就会执行case n及其下面所有语句

void  main() {
	int a = 1, b = 2;
	switch (a + b) { //表达式
	case 2:
		printf("%d", a);
		break;
	case 3:
		printf("%d", b);
		break;
	case 4:
		printf("%d", a+b);
		break;
	default:
		printf("nothing new");
	}
}

数组

初始化数组
int a[10] = {5,4,3,2,1};

未被赋值的数据根据编译器不同会赋予不同的默认值,一般情况默认是0

所有数据置0
//这两种方法都可以
int a[10] = {0};
int a[10] = {};
//memset
#include<string.h>
void main() {
	int a[5] = { 1,2,3,4,5 };
	memset(a, 0, sizeof(a));
	for (int i = 0; i < 5; i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
}
----------------
0 0 0 0 0

string.h头文件

包含了对字符数组操作的函数

int strlen(str)

返回字符数组第一个\0前的字符数

void main() {
	char str[10];
	gets_s(str);
	int len = strlen(str);
	printf("%d", len);
}
--------------------
agsol
5

int strcmp(str1,str2)

从前到后依次比较大小,

1<2,返回一个负整数

1==2,返回0

1>2,返回一个正整数

strcpy(str1,str2)

把str2复制给str1,包括\0

strcat(str1,str2)

把str2接到str1后面

指针

什么是指针

指针是一个unsigned类型整数

&用来取地址

*用来取指针对应的值

*是变量类型的一部分

//c程序员习惯
int *p;
//c++程序员习惯
int* p;
//多个同种类型指针
int *p1,p2;//p1是int*,p2是int
//多个同种应该这样定义
int *p1, *p2, *p3;

指针变量

void main() {
	int a;
	int* p = &a;
	a = 233;
	printf("%d\n", *p);
	printf("%d\n", a);
}
-----------------------
233
233

基类型

指针只能指向自己基类型的变量

int*的基类型是int,int*所指向的数据只能是int

指针和数组

指针变量是可以加减法的,常用于数组中,相当于i++.

void main() {
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (int i = 0; i < 10; i++) {
		printf("%d,", a[i]);
	}
	printf("\n");
	for (int* p = a; p < a + 10; p++) {
		printf("%d,", *p);
	}
}
----------------------------------------
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
等价写法

*(p+i)==a[i]

指针变量作为函数参数

交换俩个数,不变版本

void swap(int a, int b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
}

void main() {
	int a = 1, b = 2;
	swap(a, b);
	printf("a=%d,b=%d\n", a, b);
}
----------------------------
a=1,b=2

指针版本

void swap(int* a, int* b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

void main() {
	int a = 1, b = 2;
	int* p1 = &a, * p2 = &b;
	swap(p1, p2);
	printf("a=%d,b=%d\n", *p1, *p2);
}
-----------------------------------
a=2,b=1
注意
void swap(int* a, int* b) {
	int* temp = a;
	a = b;
	b = temp;
}

这样的写法是错误的,不可以直接交换两个数据的地址

因为地址本质上是一个无符号数.对地址本身进行修改与传入普通的变量没有区别,都是副本

引用

c++中的语法,在函数参数中加&,表示引用

void change(int& n) {
	n = 1;
}
void main() {
	int a = 10;
	printf("%d\n", a);
	change(a);
	printf("%d\n", a);
}
-----------------------
10
1

指针的引用

将a和b的地址调换了

void swap(int*& p1, int*& p2) {
	int* temp = p1;
	p1 = p2;
	p2 = temp;
}

void main() {
	int a = 1, b = 2;
	int* p1 = &a, * p2 = &b;
	printf("p1=%d,p2=%d\n", p1, p2);
	printf("a=%d,b=%d\n", *p1, *p2);
	swap(p1, p2);
	printf("p1=%d,p2=%d\n", p1, p2);
	printf("a=%d,b=%d\n", *p1, *p2);
}
---------------------------------
p1=13629800,p2=13629788
a=1,b=2
p1=13629788,p2=13629800
a=2,b=1

结构体

typedef struct studentInfo {
	int id;
	char name[10];
	studentInfo* next;
}str,*p;

访问结构体

stu.id;
stu->id;
(*p).id;
(*p)->id;
p->id;//通过指针简介的写法

结构体初始化

普通的结构体内部会生成一个默认的构造函数

也可以自定义初始化函数,但是如果自定义了初始化函数,则不能不经初始化就定义结构体变量

struct studentInfo {
	int id;
	char gender;
	//默认生成的构造函数
	studentInfo(){}
	//只初始化gender
	studentInfo(char _gender) {
		gender = _gender;
	}
	//两个都初始化
	studentInfo(int _id, char _gender) {
		//赋值
		id = _id;
		gender = _gender;
	}
};

studentInfo stu1 = studentInfo(007, 'M');
studentInfo stu2 = studentInfo('F');

误差

在编译后解决误差的问题

#include<math.h>
const double eps = 1e-8;
//==
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
//>
#define More(a,b) (((a)-(b))>(eps))
//<
#define Less(a,b) (((a)-(b))<(-eps))
//>=
#define MoreEqu(a,b) (((a)-(b))>(-eps))
//<=
#define LessEqu(a,b) (((a)-(b))<(eps))
//pai
const double Pi = acos(-1.0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值