《算法笔记》第2章 C/C++快速入门

2.0.1 a+b

#include

int main(){

         int a, b;

         scanf("%d%d", &a, &b);

         printf("%d", a+b);

         return 0;

}

 

2.1.1 a+b

#include

int main(){

         int a = 1, b = 2;

         printf("%d", a+b);

         return 0;

}

 

2.1.2 a+b f

#include

int main(){

         double a = 3.14, b = 0.12;

         double c = a + b;

         printf("%f", c);

         return 0;

}

 

2.1.3 字符型

#include

//notice: 0-9,A-Z,a-z对应的ASCII码分别是48-57,65-90,7-122,小写字母的ASCII码比大写字母的大32

int main(){

         char c1 ='z', c2 = 'j', c3 = 117;

         printf("%c%c%C", c1, c2, c3);

         return 0;

}

 

2.1.4 转义字符

#include

//notice: \0是空字符NULL,不是空格

int main(){

         int num1 = 1, num2 = 2;

         printf("%d\n\n%d", num1, num2);

         printf("%c", 7);

         return 0;

}

 

2.1.5 字符串常量

#include

//notice: 不能把字符串常量赋值给字符变量,如char c = "abcd"的写法是不允许的。

int main(){

         char str1[25] = "wo ai de ren bu ai wo";

         char str2[25] = "so sad a story it is.";

         printf("%s, %s", str1, str2);

         return 0;

}

 

2.1.6 布尔型

#include

//notice: 整型常量在赋值给布尔型变量时会自动转换为true(非零)或者false(零),非零包括正整数和负整数,1和-1都会转为true

int main(){

         bool flag1 = 0, flag2 = true;

         int a = 1, b = 1;

         printf("%d %d %d", flag1, flag2, a==b);

         return 0;

}

 

2.1.7 强制类型转换

#include

 

int 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);

         return 0;

}

 

2.1.8 符号常量

#include

#define pi 3.14

int main(){

         double r = 3;

         printf("%f\n", pi * r * r);

         return 0;

}

 

2.1.9 const常量

#include

const double pi = 3.14;

int main(){

         double r = 3;

         printf("%f\n", 2 * pi * r);

         return 0;

}

 

2.1.10 define

#include

#define ADD(a, b) ((a)+(b))

#define CAL(x) (x *2 + 1)

// notice: 宏定义时直接将对应的部分替换,然后才进行编译和运行

int main(){

         int num1 = 3, num2 = 5;

         printf("%d\n", ADD(num1, num2));

         int a = 1;

         printf("%d\n", CAL(a + 1)); // 原封不动替换,实际上是(a + 1 * 2 +1),结果是4而不是((a + 1) * 2 + 1) = 5

         return 0;

}

 

2.1.11 运算符

#include

 

int main(){

         int a = 3, b = 4;

         double c = 1.23, d = 0.24;

         printf("%d %d\n", a + b, a - b);

         printf("%f\n", c * d);

         return 0;

}

 

2.1.12 除法运算 向下取整

#include

// notice: 整数除法并不会得到一个double浮点数型的数,而是直接舍去小数部分(即向下取整)

int main(){

         int a = 5, b = 4, c = 5, d = 6;

         printf("%d %d %d\n", a / b, a / c, a / d);

         return 0;

}

 

2.1.13 取模运算

#include

// notice: 取模运算符的优先级与除法相同

int main(){

         int a = 5, b = 3, c = 5;

         printf("%d %d\n", a % b, a % c);

         return 0;

}

 

2.1.14 自增运算符

#include

// notice: i++是先使用i再将i加1,而++i则是先将i加1再使用i

int main(){

         int a = 1, b = 1, n1, n2;

         n1 = a++;

         n2 = ++b;

         printf("%d %d\n", n1, a);

         printf("%d %d\n", n2, b);

         return 0;

}

 

2.1.15 六种关系运算符

#include

// notice: 表达式成立返回真(1,true),不成了时返回假(0, false)

int main(){

         int a = 1, b = 2, c = 1;

         printf("%d\n", a

         printf("%d\n", a>b);

         printf("%d\n", a<=c);

         printf("%d\n", a>=c);

         printf("%d\n", a==b);

         printf("%d\n", a!=b);

         return 0;

}

 

2.1.16 三种逻辑运算符

#include

// notice: 表达式成立返回真(1,true),不成了时返回假(0, false)

int main(){

         int a = 1, b = 0, c = 1;

         printf("%d\n", a&&b);

         printf("%d\n", a||b);

         printf("%d\n", !c);

         return 0;

}

 

2.1.17 条件运算符

#include

#define MAX(a, b) ((a) > (b) ? (a) : (b))

// notice: A ? B:C,为C语言中唯一的三目运算符,含义是如果A为真,那么执行并返回B;如果A为假那么执行并返回C。

int main(){

         int a = 3, b = 5;

         int c = a > b ? 7 : 11;

         printf("%d\n", c);

         printf("%d\n", MAX(a, b));

         return 0;

}

 

2.1.18 位运算符

#include

 

int main(){

         const int INF = (1 << 30) - 1; // 必须加括号,因为位运算的优先级低于算数运算符

         // const int INF = 0x3fffffff;  与上式等价

         return 0;

}

 

2.2.1 赋值表达式

#include

 

int main(){

         int n = 3 * 2 + 1;

         int m = (n > 6) && (n < 8);

         n = n + 2;

         int p , q;

         p = q = 5; // 多个变量赋同一个值

         printf("%d, %d, %d, %d\n", n, m, p, q);

         return 0;

}

 

2.2.2 赋值表达式-2

#include

//notice: 赋值运算可以通过将运算符放在前面来实现赋值操作的简化

int main(){

         int n = 12, m = 3;

         n /= m + 1; // 等价于 n /= (m + 1)

         m %= 2;

         printf("%d, %d\n", n, m);

         return 0;

}

 

2.2.3 输入输出

#include

 

int main(){

         int hh, mm, ss;

         printf("请输入一个时间(hh:mm:ss):\n");

         scanf("%d:%d:%d", &hh, &mm, &ss);

         printf("%d:%d:%d", hh, mm, ss);

         return 0;

}

 

2.2.4 输入输出-2

#include

//notice: 数组名称本身就代表了这个数组的第一个元素,所以不需要再加取地址运算符

int main(){

         int a;

         long long b;

         float c;

         double d;

         char e;

         char f[10];

         printf("请输入一个整数:");

         scanf("%d", &a);

         printf("请输入一个长整数:");

         scanf("%lld", &b);

         printf("请输入一个单精度浮点数:");

         scanf("%f", &c);

         printf("请输入一个双精度浮点数:");

         scanf("%lf", &d);

         getchar(); // getchar可以识别换行

         printf("请输入一个字符:");

         scanf("%c", &e); // scanf的%c格式可以读入空格和换行

         printf("请输入一个字符串:");

         scanf("%s", f); // char数组输入不加&

         printf("你的输入是:%d, %lld, %f, %lf, %c, %s", a, b, c, d, e, f);

         return 0;

}

 

2.2.5 输入输出-3

#include

//notice: 如果要输入“3 4”这种用空格隔开的的两个数字,两个%d之间可以不加空格

int main(){

         int a, b;

         printf("请输入两个整数,用空格隔开:");

         scanf("%d%d", &a, &b); // 原因是除%c,外scanf对其他格式符(如%d)的输入是以空白符为结束判断标志的

         printf("你的输入是:%d, %d\n", a, b);

         char str[10];

         printf("请输入一个字符串(xxx xxx):");

         scanf("%s", str); // 字符数组使用%s读入时以空格和换行为读入结束的标志

         printf("你的输入是:%s", str);

         return 0;

}

 

2.2.6 float与double的精度

#include

 

int main(){

         float f1 = 8765.4, f2 = 8765.4;

         double d1 = 8765.4, d2 = 8765.4;

         printf("%f\n%f", f1 * f2, d1 * d2);

         return 0;

}

 

2.2.7 转义字符

#include

 

int main(){

         printf("abcd\nefg\nhijk\nlmn\n");

         printf("%% \%\n");

         printf("\\ \&\n");

         return 0;

}

 

2.2.8 三种实用输出格式

#include

 

int main(){

         //(1)%md

         // 使不足m位的int型变量以m位进行右对齐输出,高位用空格补齐;本身超过m位则保留原样

         int a = 123, b = 1234567;

         printf("%7d\n", a);

         printf("%7d\n", b);

         //(2)%md

         // 使不足m位的int型变量以m位进行右对齐输出,高位用"0"补齐;本身超过m位则保留原样

         printf("%08d\n", a);

         printf("%08d\n", b);

         // (3)%.mf

         // 使浮点数保留m位小数输出,“四舍六入五成双”规则

         double c = 12.34567;

         printf("%.0f\n", c);

         printf("%.1f\n", c);

         printf("%.2f\n", c);

         printf("%.3f\n", c);

         printf("%.4f\n", c);

         return 0;

}

 

2.2.9 使用getchar和putchar输入输出字符

#include

 

int main(){

         char c1, c2, c3;

         c1 = getchar();

         getchar();

         c2 = getchar();

         c3 = getchar(); //输入abcd,则输出acd

         putchar(c1);

         putchar(c2);

         putchar(c3);

         return 0;

}

 

2.2.10 注释

#include

 

int main(){

         // (1) 使用“/**/”注释

         // 对“/*”和“*/”之间的内容进行注释,且可以注释若干行连续的内容

         int a, b;

         scanf("%d%d", &a, &b);

         /*a++;

         b++;

         a = a * 2; */

         printf("%d %d\n", a, b);

        

         // (2) 使用“/”注释

         // 仅对单行进行注释

         a = 2;

         b = 3;

         a++; //将a自增

         b--; //将b自减

         printf("%d %d\n", a, b);    

         return 0;

}

 

2.2.11 typedef

#include

typedef long long LL; // 给long long起个别名LL

//notice: typedef能给复杂的数据起一个别名

int main(){

         LL a = 123456789012345, b = 234567890123456;

         printf("%lld", a + b);   

         return 0;

}

 

2.2.12 常用math函数

#include

#include // 数学函数头文件

int main(){

         //(1) fabs(double x), 取绝对值

         double db = -12.56;

         printf("%.2f\n", fabs(db));

        

         //(2) floor(double x)和ceil(double x), 向下取整和向上取整

         double db1 = -5.2, db2 = 5.2;

         printf("%.0f %.0f\n", floor(db1), ceil(db1));

         printf("%.0f %.0f\n", floor(db2), ceil(db2));

        

         //(3) pow(double r, double p), 返回r^p;

         db = pow(2.0, 3.0);

         printf("%f\n", db);

        

         //(4) sqrt(double x), 返回x的算术平方根

         db = sqrt(2.0);

         printf("%f\n", db);      

         return 0;

}

 

2.2.13 常用math函数-2

#include

#include // 数学函数头文件

const double pi = acos(-1);

int main(){

         //(5) log(double x) 返回以自然对数e为底的对数

         double db = log(1.0);

         printf("%f\n", db);

         //C语言没有对任意底数求对数的函数,必须使用换底公式:loga b = (loge b) / (loge a)

        

         //(6) sin(double x), cos(double x), tan(double x), 分别为正弦、余弦、正切函数,参数要求弧度制

         double db1 = sin(pi * 45 / 180);

         double db2 = cos(pi * 45 / 180);

         double db3 = tan(pi * 45 / 180);

         printf("%f, %f, %f\n", db1, db2, db3);

        

         //(7) asin(double x), acos(double x), atan(double x), 分别为反正弦、反余弦、反正切函数,参数要求弧度制

         db1 = asin(1);

         db2 = acos(-1.0);

         db3 = atan(0);

         printf("%f, %f, %f\n", db1, db2, db3);

        

         //(8) round(double x), 四舍五入

         db1 = round(3.45);

         db2 = round(3.55);

         db3 = round(3.65);

         printf("%f, %f, %f\n", db1, db2, db3);

         return 0;

}

 

2.3.1 if语句

#include

 

int main(){

         int n = 2;

         if(n > 3){

                   n = 9;

                   printf("%d\n", n);

         } else if(n > 2){

                   printf("%d\n", n + 1);

         } else {

                   printf("%d\n", n);

         }

         return 0;

}

 

2.3.2 if语句-2

#include

// notice: if条件中,表达式“!=0”或“==0”可简写

int main(){

         //(1) 表达式是“!=0”可省略

         int n = 0, m = 5;

         if(n){

                   printf("n is not zero!\n");

         } else {

                   printf("n is zero!\n");

         }

         if(m){

                   printf("m is not zero!\n");

         } else {

                   printf("m is zero!\n");

         }

        

         //(2) 表达式是“==0”可省略并在表达式前加非运算符“!”

         if(!n){

                   printf("n is zero!\n");

         } else {

                   printf("n is not zero!\n");

         }

         if(!m){

                   printf("m is zero!\n");

         } else {

                   printf("m is not zero!\n");

         }

         return 0;

}

 

2.3.3 if语句的嵌套

#include

 

int main(){

         int n = 3, m = 5;

         if(n < 5){

                   if(m < 5){

                            printf("%d\n", m + n);

                   } else {

                            printf("%d\n", m - n);

                   }                

         } else {

                   printf("haha\n");

         }

         return 0;

}

 

2.3.4 switch语句

#include

 

int main(){

         int a = 1, b = 2;

         switch(a + b){

                   case 2:

                            printf("%d\n", a);

                            break;

                   case 3:

                            printf("%d\n", b);

                            break;

                   case 4:

                            printf("%d\n", a + b);

                            break;

                   default:

                            printf("sad story\n");

         }

         return 0;

}

 

2.3.5 switch语句2

#include

//notice: break语句用于结束当前switch语句,如果将其删去,则程序将会从第一个匹配的case开始执行语句,直到所有语句执行完毕后退出switch

int main(){

         int a = 1, b = 2;

         switch(a + b){

                   case 2:

                            printf("%d\n", a);

                   case 3:

                            printf("%d\n", b);

                   case 4:

                            printf("%d\n", a + b);

                   default:

                            printf("sad story\n");

         }

         return 0;

}

 

2.4.1 while语句

#include

 

int main(){

         int n = 1, sum = 0;

         while(n <= 100){

                   sum = sum + n;

                   n++;

         }

         printf("sum = %d\n", sum);

         return 0;

}

 

2.4.2 while语句2

#include

 

int main(){

         int n = 12345, count = 0;

         while(n){ // 相当于while(n != 0)

                   count = count + n % 10;

                   n = n / 10;

         }

         printf("%d\n", count);

         return 0;

}

 

2.4.3 do while语句

#include

 

int main(){

         int n = 1, sum = 0;

         do{

                   sum = sum + n;

                   n++;

         }

         while(n <= 100);

         printf("sum = %d\n", sum);

         return 0;

}

 

2.4.4 for语句

#include

//notice: 在C语言中不允许在for语句里定义变量,但在C++中可以

int main(){

         int i, sum = 0;

         for(i = 1; i <= 100; i++){

                   sum = sum + i;

         }

         printf("sum = %d\n", sum);

         return 0;

}

 

2.4.5 break语句

#include

//notice: 在C语言中不允许在for语句里定义变量,但在C++中可以

int main(){

         int i, sum = 0;

         for(i = 1; i <= 100; i++){

                   sum = sum + i;

                   if(sum >= 2000) break;

         }

         printf("sum = %d\n", sum);

         return 0;

}

 

2.4.5 continue语句

#include

//notice: 在C语言中不允许在for语句里定义变量,但在C++中可以

int main(){

         int sum = 0;

         for(int i = 1; i <= 5; i++){

                   if(i % 2) continue; // 这里(i % 2 == 1)等价于if(i % 2) 

                   sum = sum + i;

         }

         printf("sum = %d\n", sum);

         return 0;

}

 

2.5.1 一维数组

#include

//notice: 数组大小必须是整数常量,不可以是变量;数组下标从0开始

int main(){

         // 一维数组定义举例

         int a[10] = {5, 3, 2, 6, 8, 4}; // 前六个元素赋值,后面未赋值的元素默认为0

         double db[233];

         char str[1000];

         bool HashTable[100];

        

         for(int i = 0; i < 10; i++){

                   printf("a[%d] = %d\n", i, a[i]);

         }

         return 0;

}

 

2.5.2 一维数组递推

#include

//notice: 数组大小必须是整数常量,不可以是变量;数组下标从0开始

int main(){

         // 一维数组定义举例

         int a[10] = {0}; // 要想给整个数组都赋值为0,只需把第一个元素赋值为0,或者只用一个大括号来表示

         int b[10] = {};

         for(int i = 0; i < 10; i++) printf("%d ", a[i]);

         printf("\n");

         for(int i = 0; i < 10; i++) printf("%d ", b[i]);

         printf("\n");

        

         //递推 可分为顺推和逆推

         scanf("%d", &a[0]);

         for(int i = 1; i < 10; i++) a[i] = a[i - 1] * 2; // 顺推将数组后续元素都赋值为前一个元素的两倍

         for(int i = 0; i < 10; i++) printf("%d ", a[i]);

         return 0;

}

 

2.5.3 冒泡排序

#include

//notice: 数组大小必须是整数常量,不可以是变量;数组下标从0开始

int main(){

         int a[10] = {3, 1, 4, 5, 2};

         for(int i = 1; i <= 4; i++){ // 进行n-1趟排序;

                   // 第i趟时从a[0]到a[n - i - 1]都与它们下一个数比较;

                   for(int j = 0; j < 5 - i; j++){

                            if(a[j] > a[j + 1]){

                                     int temp = a[j];

                                     a[j] = a[j + 1];

                                     a[j + 1] = temp;

                            }                         

                   }

         }

         for(int i = 0; i < 5; i++) printf("%d ", a[i]);

         return 0;

}

 

2.5.4 二维数组

#include

//notice: 一维二维的下标都是从0开始

int main(){

         int a[5][6] = {{3, 1, 2}, {8, 4}, {}, {1, 2, 3, 4, 5}};

         for(int i = 0; i < 5; i++){

                   for(int j = 0; j < 6; j++){

                            printf("%d ", a[i][j]);

                   }

                   printf("\n");

         }

         return 0;

}

 

2.5.5 二维数组对应元素相加

#include

//notice: 一维二维的下标都是从0开始

int main(){

         int a[3][3], b[3][3];

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            scanf("%d", &a[i][j]); // 输入二维数组a的元素

                   }

         }

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            scanf("%d", &b[i][j]); // 输入二维数组b的元素

                   }

         }

         int c[3][3];

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            c[i][j] = a[i][j] + b[i][j]; // 对应位置元素相加并放到二维数组c中

                   }

         }

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            printf("%d ", c[i][j]); // 输出二维数组c的元素

                   }

                   printf("\n");

         }

         return 0;

}

 

2.5.6 大数组

#include

/*notice: 如果数组元素较大(大概10^6级别),则需要将其定义在主函数外面,否则会使程序异常退出

原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大 */

int a[1000000];

int main(){

         for(int i = 0; i < 1000000; i++){

                   a[i] = i;

         }

         return 0;

}

 

2.5.7 多维数组

#include

 

int main(){

         int a[3][3][3];

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            for(int k = 0; k < 3; k++){

                                     a[i][j][k] = i + j + k;

                            }

                   }

         }

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            for(int k = 0; k < 3; k++){

                                     printf("%d ", a[i][j][k]);

                            }

                            printf("\n");

                   }

                   printf("\n");

         }

         return 0;

}

 

2.5.8 memset对数组每个元素赋同一值

#include

#include // 使用memset需加sring.h头文件

/*nitice: memset使用的是按字节赋值。而由于0的二进制补码为全0,-1的二进制补码为全1,不容易弄错。

对数组赋其他值可以使用fill函数(但memset执行较快) */

int main(){

         int a[5] = {1, 2, 3, 4, 5};

         // 赋初值0

         memset(a, 0, sizeof(a));

         for(int i = 0; i < 5; i++){

                   printf("%d ", a[i]);

         }

         printf("\n");

         // 赋初值-1

         memset(a, -1, sizeof(a));

         for(int i = 0; i < 5; i++){

                   printf("%d ", a[i]);

         }

         printf("\n");

         return 0;

}

 

2.5.9 字符数组的初始化

#include

 

int main(){

         char str1[15] = {'G', 'o', 'o', 'd', ' ', 's', 't', 'o', 'r', 'y', '!'};

         for(int i = 0; i < 11; i++){

                   printf("%c", str1[i]);

         }

         printf("\n");

        

         char str2[20] = "Good story! 2020"; // 字符数组也可以直接赋值字符串来初始化,仅限于初始化

         for(int i = 0; i < 16; i++){

                   printf("%c", str2[i]);

         }

         return 0;

}

 

2.5.10 scanf输入printf输出

#include

 

int main(){

         char str[10];

         scanf("%s", str);

         printf("%s", str);

         return 0;

}

 

2.5.11 gatchar输入putchar输出

#include

//notice: getchar和putchar分别用来输入输出单个字符

int main(){

         char str[5][5];

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            str[i][j] = getchar();

                   }

                   getchar(); // 这句是为了把每行末尾的换行符吸收掉

         }

         for(int i = 0; i < 3; i++){

                   for(int j = 0; j < 3; j++){

                            putchar(str[i][j]);

                   }

                   putchar('\n');

         }

         return 0;

}

 

2.5.12 gets输入puts输出

#include

//notice: gets识别换行符\n作为输入结束,因此scanf完一个整数后,如果要使用gets,需要先用getchar接收整数后的换行符

int main(){

         char str1[20];

         char str2[5][10];

         gets(str1); // gets用来输入一行字符串,并将其存放于一维数组中(或二维数组的一维)

         for(int i = 0; i < 3; i++){

                   gets(str2[i]);

         }

         puts(str1); // puts用来输出一行字符串,将一维数组(或二维数组的一维)输出,并紧跟一个换行

         for(int i = 0; i < 3; i++){

                   puts(str2[i]);

         }

         return 0;

}

 

2.5.13 字符数组的存放方式

#include

/*notice: 字符数组的每一位都是一个char字符,末尾都有一个空字符\0,表示存放的字符串的结尾。

空字符\0在使用gets或scanf输入字符串时会自动添加在输入的字符串后面,并占用一个字符位,而puts与printf就是通过识别\0作为之非常的结尾。

结束符\0的ASCII码为0,即空字符NULL。与空格不同,空格的ASCII码为32.

 

如果不是使用scanf函数的%s格式或gets函数输入字符串(如getchar),请一定要在输入的每个字符串后加入“\0”,

否则printf和puts输出字符串会因无法识别字符串末尾而输出乱码

 */

int main(){

         char str[15];

         for(int i = 0; i < 3; i++){

                   str[i] = getchar();

         }

         puts(str);

         return 0;

}

 

2.5.14 string头文件 strlen

#include

#include

int main(){

         char str[15];

         gets(str);

         int len = strlen(str);

         printf("%d\n", len);

         return 0;

}

 

2.5.15 string头文件 strcmp

#include

#include

/*notice: strcmp函数返回两个字符串大小的比较结果,比较原则是按字典序

strcmp的返回结果:

1.如果字符数组1 < 字符数组2,则返回一个负整数(不同编译器不同,不一定是-1)

2.如果字符数组1 = 字符数组2,则返回0

3.如果字符数组1 > 字符数组2,则返回一个正整数(不同编译器不同,不一定是+1)

*/

int main(){

         char str1[15], str2[15];

         gets(str1);

         gets(str2);

         int cmp = strcmp(str1, str2);

         if(cmp < 0) printf("str1 < str2\n");

         else if(cmp > 0) printf("str1 > str2\n");

         else printf("str1 == str2\n");

         return 0;

}

 

2.5.16 string头文件 stecmp

#include

#include

 

int main(){

         char str[15];

         gets(str);

         int len = strlen(str);

         printf("%d\n", len);

         return 0;

}

 

2.5.16 string头文件 strcpy

#include

#include

//notice: strcpy(str1, str2)函数把str2复制给str1, 包含结束符\0

 

int main(){

         char str1[15] = "abcd", str2[15] = "efgh";

         strcpy(str1, str2);

         puts(str1);

         return 0;

}

 

2.5.17 string头文件 strcat

#include

#include

//notice: strcat(str1, str2)函数把str2接到str1后面

 

int main(){

         char str1[15] = "abcd", str2[15] = "efgh";

         strcat(str1, str2);

         puts(str1);

         return 0;

}

 

2.5.18 sscanf与sprintf

#include

 

int main(){

         int n;

         char str[100] = "12345";

         sscanf(str, "%d", &n); // sscanf把字符数组str中的内容以“%d”的格式写到n中(从左到右)

         printf("%d\n", n);

        

         sprintf(str, "%d", n); // sprintf把n中的内容以“%d”的格式写到字符数组str中(从右到左) 

         printf("%s\n", str);

         return 0;

}

 

2.5.19 sscanf与sprintf

#include

 

int 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);

        

         char str3[100];

         sprintf(str3, "%d:%lf,%s", n, db, str2);

         printf("str3 = %s\n", str3);

         return 0;

}

 

2.6.1 函数的定义

#include

 

void print1(){ // void含义是“空”,即不返回任何东西

         printf("Haha, \n");

         printf("Good idea!\n");

}

 

void print2(){ // 括号里没有任何参数,称为无参函数;而fabs(x),pow(r,p)称为有参函数

         printf("Ohno, \n");

         printf("Bad idea!\n");

}

 

int main(){

         print1();

         print2();

         return 0;

}

 

2.6.2 函数的定义2

#include

 

int judge(int x){

         if(x > 0) return 1;

         else if(x == 0) return 0;

         else return -1;

}

 

int main(){

         int a, ans;

         scanf("%d", &a);

         ans = judge(a);

         printf("%d\n", ans);

         return 0;

}

 

2.6.3 全局变量

#include

int x; // 全局变量x

void change(){

         x = x + 1;

}

int main(){

         x = 10; // 全局变量x

         change();

         printf("%d\n", x);

         return 0;

}

 

2.6.4 局部变量

#include

 

void change(int x){ // 式参数或形参:函数定义的小括号内的参数为形

         x = x + 1;

}

int main(){

         int x = 10;

         change(x); // change函数的参数x为局部变量,仅在函数内部有效,通过x传进去的只是一个副本

                               // 实际参数或实参:实际调用时小括号内的参数

         printf("%d\n", x);

         return 0;

}

 

2.6.5 多个参数的函数

#include

 

int MAX(int a, int b, int c){ // 即使参数类型都相同也不能省略

         int M;

         if(a >= b && a >= c) M = a;

         else if(b >= a && b >= c) M = b;

         else M = c;

         return M;

}

 

int main(){

         int a, b, c;

         scanf("%d%d%d", &a, &b, &c);

         printf("%d\n", MAX(a, b, c));

         return 0;

}

 

2.6.6 main函数

#include

 

int MAX(int a, int b, int c){ // 即使参数类型都相同也不能省略

         int M;

         if(a >= b && a >= c) M = a;

         else if(b >= a && b >= c) M = b;

         else M = c;

         return M;

}

 

//notice: 主函数对一个程序来说只能有一个,并且无论主函数写在哪个位置,整个程序一定是从主函数的第一个语句开始执行,然后在需要调用其他函数时才去调用

int main(){

         int a, b, c;

         scanf("%d%d%d", &a, &b, &c);

         printf("%d\n", MAX(a, b, c));

         return 0; // main函数返回0告知系统程序正常终止

}

 

2.6.7 以数组作为函数参数

#include

//notice: 数组作为参数时,在函数中的修改也就等同于对原数组元素的修改

void change(int a[], int b[][5]){ //参数中数组的第一维不需要填写长度,如果是二维数组,那么第二维需要填写长度

         a[0] = 1;

         a[1] = 3;

         a[2] = 5;

         b[0][0] = 1;

}

 

int main(){

         int a[3] = {0};

         int b[5][5] = {0};

         change(a, b); // 实际调用时只需填写数组名

         for(int i = 0; i < 3; i++){

                   printf("%d\n", a[i]);

         }

         return 0;

}

 

2.6.8 函数的嵌套调用

#include

 

int max_2(int a, int b){

         if(a > b) return a;

         else return b;

}

int max_3(int a, int b, int c){

         int temp = max_2(a, b);

         temp = max_2(temp, c);

         return temp;

}

 

int main(){

         int a, b, c;

         scanf("%d%d%d", &a, &b, &c);

         printf("%d\n", max_3(a, b, c));

         return 0;

}

 

2.6.9 函数的递归调用

#include

 

int F(int n){

         if(n == 0) return 1;

         else return F(n - 1) * n;

}

 

int main(){

         int n;

         scanf("%d", &n);

         printf("%d\n", F(n));

         return 0;

}

 

2.7.1 指针

#include

 

int main(){

         int a = 1;

         printf("%d, %d", &a, a); // 指针是一个unsigned类型的整数

         return 0;

}

 

2.7.2 指针变量

#include

//notice:星号“*”在数据类型之后或是变量名之前都可以,星号是类型的一部分

int main(){

         int a = 1, b = 2;

         int *p1 = &a, *p2 = &b; // p是变量名,用来存储地址,地址&a是赋值给p而不是*p

         int* p3, p4; // 星号只会结合于第一个变量名

         printf("%d %d\n", *p1, *p2); // 可将星号*视为一把开启房间的钥匙,可以把房间打开,从而获得变量的值

         return 0;

}

 

2.7.3 指针变量2

#include

//notice:星号“*”在数据类型之后或是变量名之前都可以,星号是类型的一部分

int main(){

         int a = 1, b = 2;

         int *p1 = &a, *p2 = &b; // p是变量名,用来存储地址,地址&a是赋值给p而不是*p

         int* p3, p4; // 星号只会结合于第一个变量名

         printf("%d %d\n", *p1, *p2); // 可将星号*视为一把开启房间的钥匙,可以把房间打开,从而获得变量的值

         *p1 = 5;

         *p2 = 6; // *p是这个地址中存放的元素,对*p进行赋值,也可以改变保存的元素

         printf("%d %d\n", *p1, *p2);

         return 0;

}

 

2.7.4 指针与数组

#include

//notice: 数组名称也作为数组的首地址使用

int main(){

         int a[10] = {1};

         int* p = a; // a作为数组a的首地址&a[0]而被赋值给指针变量p,因此输出*p其实就是输出a[0]

         printf("%d\n", *p);

         return 0;

}

 

2.7.4 指针与数组2

#include

 

int main(){

         int a[10];

         for(int i = 0; i < 10; i++){

                   scanf("%d", a + i); // a+i和&a[i]等价

         }

         for(int i = 0; i < 10; i++){

                   printf("%d ", *(a + i)); // a+i是地址

         }

         return 0;

}

 

2.7.4 指针与数组3

#include

 

int main(){

         int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

         for(int* p = a; p < a + 10; p++){

                   printf("%d ", *p); // a+i是地址

         }

         return 0;

}

 

2.7.5 指针与数组4

#include

 

int main(){

         int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

         int* p = a;

         int* q = &a[5];

         printf("q = %d\n", q);

         printf("p = %d\n", p);

         printf("q - p = %d\n", q - p); // q-p指两个地址之间的距离,以int为单位

         return 0;

}

 

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

#include

 

void change(int* p){

         *p = 233;

}

int main(){

         int a = 1, b = 2;

         int *p = &a;

         change(p); // 地址传递

         printf("%d\n", a);

         return 0;

}

 

2.7.7 交换变量值

#include

 

void swap(int a, int b){ // 函数在接受参数过程中是单向一次性的值传递,调用swap(a, b)时只是把a和b的值复制进去,不会改变原变量值

         int temp = a;

         a = b;

         b = temp;

}

int main(){

         int a = 1, b = 2;

         swap(a, b);

         printf("a = %d, b = %d\n", a, b);

         return 0;

}

 

2.7.7 交换变量值2

#include

 

void swap(int* a, int* b){ // 只有在获取地址的情况下对元素进行操作,才能真正地修改变量

         int temp = *a;

         *a = *b;

         *b = temp;

}

 

//错误写法1

//void swap(int* a, int* b){

//     int* temp; // 在定义指针变量temp时,temp没有被初始化,指针变量temp中存放的地址是随机的,如果该地址指向系统工作空间,那就会出错(大概率)

//     *temp = *a;

//     *a = *b;

//     *b = *temp;

//}

 

//错误写法2

//void swap(int* a, int* b){ // 思想:直接把两个地址交换,认为地址交换后元素就交换了

//     int* temp = a; // 函数参数的传送方式是单向一次性的,main函数传给swap函数的“地址”其实是一个“无符号整型”的数,其本身也跟普通变量一样只是“值传递”

//     a = b; // swap函数对地址本身进行修改并不能对main函数里的地址修改

//     b = temp;

//}

 

int main(){

         int a = 1, b = 2;

         int *p1 = &a, *p2 = &b;

         swap(p1, p2);

         printf("a = %d, b = %d\n", *p1, *p2);

         return 0;

}

 

2.7.8 引用

#include

// notice: 引用的&与取地址运算符&区分,引用并不是取地址的意思

void change(int&x){ // 引用不产生副本,而是给变量起了个别名;对引用变量的操作就是对原变量的操作; &加在int后面或者变量名前面都可以

         x = 1;

}

 

int main(){

         int a = 10;

         change(a);

         printf("%d\n", a);

         return 0;

}

 

2.7.9 指针的引用

#include

 

void swap(int* &p1, int* &p2){ //

         int* temp = p1;

         p1 = p2;

         p2 = temp;

}

 

int main(){

         int a = 1, b = 2;

         int *p1 = &a, *p2 = &b;

         swap(p1, p2);

         printf("a = %d b = %d\n", *p1, *p2);

         return 0;

}

 

2.8.1 结构体的定义

#include

 

int main(){

         struct studentInfo{ //结构体里面能定义除了自己本身之外的任何数据类型

                   int id;

                   char gender; // 'F' or 'M'

                   char name[20];

                   char major[20];

                   studentInfo* Chen; //但可以定义自身类型的指针变量

         }Alice, Bob, stu[1000];

         return 0;

}

 

2.8.2 访问结构体内的元素

#include

 

int main(){

         struct studentInfo{ //结构体里面能定义除了自己本身之外的任何数据类型

                   int id;

                   char gender; // 'F' or 'M'

                   char name[20];

                   char major[20];

                   studentInfo* next; //但可以定义自身类型的指针变量

         }stu, *p;

         printf("%d %s %s\n", stu.id, stu.name, stu.major); // "."操作

         printf("%d %s %s\n", (*p).id, (*p).name, (*p).major); // "."操作

         printf("%d %s %s\n", p->id, p->name, p->major); // "->"操作

         return 0;

}

 

2.8.3 结构体的初始化

#include

#include

 

int main(){

         //定义

         struct studentInfo{ //结构体里面能定义除了自己本身之外的任何数据类型

                   int id;

                   char gender; // 'F' or 'M'

                   char name[20];

                   char major[20];

                   studentInfo* next; //但可以定义自身类型的指针变量

         }stu, *p;

        

         //初始化

         stu.id = 20201001; //或者在输入是赋值

         stu.gender = 'M'; //scanf("%d %c", &stu.id, &stu.gender);

         strcpy(stu.name, "Bob");

         strcpy(stu.major, "Computer Science");

         p = &stu;

        

         //访问元素

         printf("%d %c %s %s\n", stu.id, stu.gender, stu.name, stu.major); // "."操作

         printf("%d %c %s %s\n", (*p).id, (*p).gender, (*p).name, (*p).major); // "."操作

         printf("%d %c %s %s\n", p->id, p->gender, p->name, p->major); // "->"操作

         return 0;

}

 

2.8.4 结构体的初始化 构造函数

#include

#include

//notice: 如果自己重新定义了构造函数,则不能不经初始化就定义结构体变量

int main(){

         //定义

         struct studentInfo{ //结构体里面能定义除了自己本身之外的任何数据类型

                   int id;

                   char gender; // 'F' or 'M'

                   char name[20];

                   char major[20];

                   //下面的参数用以对结构体内部变量进行赋值

                   studentInfo(int _id, char _gender, char _name[], char _major[]){

                            id = _id;

                            gender = _gender;

                            strcpy(name, _name);

                            strcpy(major, _major);

                   }

                   // 可以化简成一行 只初始化id,gender

                   studentInfo(int _id, char _gender): id(_id), gender(_gender) {}

                  

                   //用以不初始化就定义结构体变量

                   studentInfo() {};

                  

                   //只初始化name

                   studentInfo(char _name[]) {strcpy(name, _name);}

         };

        

         //初始化

         studentInfo stu = studentInfo(20201002, 'F', "Alice", "Math");

        

         //访问元素

         printf("%d %c %s %s\n", stu.id, stu.gender, stu.name, stu.major); // "."操作

 

         return 0;

}

 

2.8.5 结构体Point实例

#include

 

struct Point{

         int x, y;

         Point() {} //用以不经初始化地定义pt[10]

         Point(int _x, int _y): x(_x), y(_y) {} //用以提供x和y的初始化

}pt[10];

 

int main(){

         int num = 0;

         for(int i = 1; i <= 3; i++){

                   for(int j = 1; j <= 3; j++){

                            pt[num++] = Point(i, j);  //直接使用构造函数

                   }

         }

         for(int i = 0; i < num; i++){

                   printf("%d, %d\n", pt[i].x, pt[i].y);

         }

         return 0;

}

 

2.9.1 cin与cout

#include

using namespace std;

// notice: cin与cout是C++中的输入输出函数,需要添加以上两个头文件

// 无需像C语言中的scanf、printf函数那样指定输入输出格式,也不需要用取地址符&

int main(){

         int n;

         double db;

         char str[100];

         cin >> n;

         cout << n << "\n";

         cin >> db;

         cout << db << "\n";

         cin >> str;

         cout << str << "\n";

         return 0;

}

 

2.9.2 cin与cout 2

#include

#include

using namespace std;

// notice: 想要控制double型的精度,如输出小数点后2位,需要在输出之前加上一些控制信息

// 并且要加上#include头文件

 

int main(){

         //如果像要读入一行,需要使用getline函数

         char str[100];

         double a = 3.1415926;

         cin.getline(str, 100);

         cout << str << endl; // endl表示换行(end line是缩写)

         cout << setiosflags(ios::fixed) << setprecision(2) << a << "\n";

         return 0;

}

 

2.9.3 浮点数的比较

#include

#include

 

const double eps = 1e-8; // 经验表明,误差eps取10^-8是一个合适的数字

const double pi = acos(-1.0); // Π= arccos(-1)

 

// 为了方便比较,把比较操作改写成宏定义的形式:如果想使用不等于,在Equ前加“!”即可(!Equ(a, b))

#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)) // 小于等于运算符 <=

 

int main(){

         double db1 = 4 * asin(sqrt(2.0) / 2);

         double db2 = 3 * asin(sqrt(3.0) / 2);

         if(db1 == db2)

                   printf("true\n");

         else

                   printf("false\n");

         if(Equ(db1, db2))

                   printf("true\n");

         else

                   printf("false\n");

         printf("%.16f, %.16f", db1, db2);

         // db1, db2都应该是Π,但是用“==”比较会输出false

         return 0;

}

你可能感兴趣的:(C/C++,算法笔记,C/C++,算法笔记)