头图

0. 复习

0.1 循环

while(表达式)
{
}
do
{
}while(表达式);

for(初始化循环变量;判断条件;循环变量的变化)
{

}

一般比较明确循环次数的时候,使用for
不太明确循环次数的时候,一般使用while
两个控制语句:
break: 跳出循环,只能跳出当前循环(只能跳出一层循环)
continue: 直接开始下一轮循环

表达式的真假问题:
a>b a>b&&b>c 类似于这样的关系表达式或者逻辑表达式,结果只有两个:true false值就是1和0
反过来说 0是假,非零是真

int n =0;
while(n<=100)
{
  printf("%d",n);
  n++;
}
n =0;
while(101-n)
{
  printf("%d",n);
  n++;
}

0.2 预处理命令

0.2.1 #include

用于包含头文件的 <>用于编译器自带的 “”用于自己写的头文件

0.2.2 #define

无参宏

0.3 二维数组

可以看成是多个1维数组

#include <stdio.h>
int main()
{
    //二维数组的定义和初始化
    //假如方括号内的元素不够,后面就都初始化为0
    int arrTest1[3][4] = { 1,2,3,4,5,6,7 };
    // 1   2    3   4
    // 5   6    7   0
    // 0   0    0   0
    int arrTest2[3][4] = { {1,2},{3,4},{5,6} };
    // 1   2    0   0
    // 3   4    0   0
    // 5   6    0   0

    int arrTest3[][5] = { 1,2,3,4,5,6,7,8,9,10,11 };
    //等价于int arrTest[3][5] = {1,2,3,4,5,6,7,8,9,10,11};
    //1  2 3 4 5
    //6  7 8 9 10
    //11 0 0 0 0

    return 0;
}

什么时候会使用二维数组:
在一组数据中,还要再次分组的时候,需要使用二维数组。
假如有一个二维数组,如何遍历这个二维数组

1. 函数

复习:
system 执行一条CMD命令
printf 格式化输出
scanf_s 格式化输入
getchar 获取一个字符
putchar 输出一个字符
_getch 无回显的获取一个字符
strlen 求字符长度
strcat_s 拼接字符串
strcpy_s 拷贝字符串
strcmp 比较字符串

1.1 函数的基本定义格式

返回值类型   函数名称(形参列表)
{
     函数的语句;
     return 返回值;
}

函数名称:是我们自己定义的名字,名字的规则和变量名是一致:字母数字下划线 数字不能开头,不能使用关键字
返回值类型:一个函数如果需要返回一个数据作为整个函数的结果,那么就应该定义返回值类型。
return的作用:

a. 结束函数
b. 返回给函数的调用的位置一个数值,这个数值就是函数的结果。返回的数值需要和返回值类型匹配。

形参列表:我们要实现这个函数,需要什么参数,在这里规定好类型和参数个数

设计一个函数原则:
1.我们需要明确这个函数的功能是什么???一般情况下,函数的功能越单一越好,一个函数最好只解决一个问题。
2.明确了函数功能之后,需要明确需要哪些前置的数据。(我们应该如何去设计参数)
3.当功能实现完毕之后,要如何将结果告知调用者

a. 返回值
b. 也可以通过参数,传出数据
c. 也可以修改全局变量
d. 也可以将结果写入到一个文件中
e. 也可以在屏幕上输出一个结果(非常少的)

1.2 函数的使用场景

#include <stdio.h>
int main()
{
    //我们输入3个同学的名字
    //输出3个同学名字字符数量之和
    char szName1[20] = {};
    char szName2[20] = {};
    char szName3[20] = {};
    printf("请输入名字:");
    scanf_s("%s", szName1,20);
    printf("请输入名字:");
    scanf_s("%s", szName2,20);
    printf("请输入名字:");
    scanf_s("%s", szName3,20);
    int n1 = 0;
    while (szName1[n1]!=0)
    {
        n1++;
    }
    int n2 = 0;
    while (szName2[n2] != 0)
    {
        n2++;
    }
    int n3 = 0;
    while (szName3[n3] != 0)
    {
        n3++;
    }
    printf("3个同学的名字长度之和为%d", n1 + n2 + n3);


    return 0;

以上解决了问题,但是求名字长度的代码,写了3遍,万一100个学生,那重复代码就太多了。
这个时候就应该使用函数,可以少些重复代码.

#include <stdio.h>
//1.明确功能:写一个求字符数组中字符串长度的函数
//2.明确参数:字符数组
//3.明确结果如何告知调用者:通过返回值就可以 返回值类型就应该是int
//返回值类型  函数名
//{
//   具体的函数语句
//   return 返回值;
//}
int  GetStrLenth(char szBuf[20])
{
    int n2 = 0;
    while (szBuf[n2] != 0)
    {
        n2++;
    }
    return n2;
}
int main()
{
    //我们输入3个同学的名字
    //输出3个同学名字字符数量之和
    char szName1[20] = {};
    char szName2[20] = {};
    char szName3[20] = {};
    printf("请输入名字:");
    scanf_s("%s", szName1, 20);
    printf("请输入名字:");
    scanf_s("%s", szName2, 20);
    printf("请输入名字:");
    scanf_s("%s", szName3, 20);
    //使用函数的好处1:
    //定义完函数之后,调用的时候就只需要写函数名和参数,就能够使用这个功能了
    //不需要写很多重复代码
    //代码的 【复用性】就提高了
    
    //使用函数的好处2:
    //我们给这段代码起了名字,在阅读代码的时候,根据名字能够更好的理解代码逻辑
    //提高了 代码的 【可读性】
    int n1 = GetStrLenth(szName1);
    int n2 = GetStrLenth(szName2);
    int n3 = GetStrLenth(szName3);
    printf("3个同学的名字长度之和为%d", n1 + n2 + n3);
    return 0;

1.3 关于形参和实参的问题

图片.png

形参是定义函数时候,用于规定参数类型的
实参是调用函数的时候,真实传递的参数。

1.4 需要注意的地方

1.形参的改变,不会影响实参的值
图片.png
图片.png

2.如果函数的定义在调用的下面,此时编译器就不会识别这个函数,我们需要在调用之前加上函数的声明。
图片.png

练习:
实现一个函数,能够得到两个整数中的较大值。

#include <stdio.h>
int GetMax(int a, int b);
int main()
{
    int n = 10;
    int m = 20;
    int c = GetMax(n, m);
    printf("较大值为%d", c);
    return 0;
}
int GetMax(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    else
    {
        return b;
    }
}

2. 全局变量与局部变量

2.1 作用域

标识符 起作用的 代码范围
局部变量:定义在函数内部的变量,只在函数内部起作用,准确的说,是在定义它的花括号内起作用。
全局变量:定义在函数外部的变量,整个文件中的任何函数,都能访问到

2.2 局部变量和全局变量的特点

例子1,2:局部变量是在定义它的花括号内起作用。
图片.png
图片.png
例子3:小作用域覆盖大的

#include <stdio.h>
int main()
{
    int n = 100;
    if (n>5)
    {
        //同名的时候,小作用域会覆盖大作用域
        int n = 50;
        printf("%d", n);//这个位置输出的是50
    }
    printf("%d", n);//这个位置输出的是100
    return 0;
}

总结:
1.大家使用同一个全局变量
2.局部变量和全局的同名了,这就是两个变量了,在定义局部变量的函数中,使用的是局部变量
3.全局变量如果定义在了下面,上面使用的时候,就应该加声明。

#include <stdio.h>
//全局变量如果不初始化,默认就是0
//局部变量不初始化,就是随机值
extern int g_nNum;
void Fun1()
{
    g_nNum = 100;
}
void Fun2()
{
    int g_nNum = 30;
    Fun1();
    g_nNum *= 2;
}
int main()
{
    printf("%d", g_nNum);
    Fun2();
    printf("%d", g_nNum);
    return 0;
}
int g_nNum = 0;

2.3 static类型的局部变量

#include <stdio.h>
void Fun1()
{
    int nNum = 0;
    nNum++;
    printf("%d ", nNum);
}
void Fun2()
{
    //这里就定义了一个静态局部变量
    static int nNum = 0;
    nNum++;
    printf("%d ", nNum);
}
int main()
{
    for (int i = 0; i < 10; i++)
    {
        Fun1();
    }
    printf("\n");
    for (int i = 0; i < 10; i++)
    {
        Fun2();
    }
    return 0;
}

图片

普通的局部变量,在离开作用域的时候,就会被销毁掉,再次进入函数,局部变量会重新建立。
静态局部变量,再离开作用域也不销毁。下次进入函数,直接使用上一次的值。

2.4 const类型的变量

const被用于定义 不能修改的变量 (常量)
图片.png

2.5 什么是形参?什么是实参?

什么是形参?
形参全称叫做“形式参数”,也是一个虚拟的参数,在定义方法的时候使用的参数,形参是方法被调用时用于接收实参值的变量。
什么是实参?
实参全称叫做“实际参数”,顾名思义就是实际存在的参数,实参可以是常量、变量、表达式、类等,实参必须要有确定的值。
总结:形参与实参的类型、个数是要一一对应的

我们看下下面这段代码,来更加深入的了解什么是形参?什么是实参?

public class MethodTest2 {
    public static void main(String[] args) {    
        sum(4,6);//这里边的4,6就是实参
    }
    public static void sum(int a,int b){
    //sum(int a,int b)   这里边的int a,int b 就是形参 
    //它们的类型和传进来的4,6的类型和个数都是一一对应的
    //这里边的a就是4 b就是6
        int c = a + b;//相当于int c = 4 + 6;
        System.out.println("a + b = " + c);
        //结果:a+b=10
    }
}

C/C++程序的工程管理方式

3.1 基本组织方式

一个工程由多个文件组成
.cpp中写 函数与全局变量的定义。
.h中 写声明
在使用的位置,包含头文件即可。
千万不要在.h中写定义

3.2 static修饰全局变量和函数的作用

图片.png

4. 指针

三步:
定义指针变量
给指针变量赋值
解引用

#include <stdio.h>
int main()
{
    //1. 定义指针变量
    int* p1 = nullptr;//定义了一个整型指针 变量 nullptr是0 
    char* p2 = nullptr;//定义了一个字符型指针

    //2. 给指针变量赋值
    //指针应该存储的是地址
    int nNum1 = 100;
    int nNum2 = 50;
    //p存储了nNum1的地址
    //p存储了谁的地址,我们就说p指向了谁
    p1 = &nNum1;
    //3. 解引用
    //通过指针间接的访问到,它所指向的位置
    printf("%d\n", nNum1);
    printf("%d\n", *p1);
    *p1 = 500;//*p1此时就相当于是nNum1
    printf("%d\n", nNum1);
    printf("%d\n", *p1);

    p1 = &nNum2;
    *p1 = 300;
    printf("%d\n", nNum1);
    printf("%d\n", nNum2);




    return 0;
}

图片.png
图片.png

4.2 应用场景

4.2.1 场景1 在函数内部修改到函数外部的变量

#include <stdio.h>

//用一个函数,交换两个变量的值
void swap1(int a, int b)
{
    int n = a;
    a = b;
    b = n;
}
void swap2(int* p1,int * p2)
{
    int n = *p1;
    *p1 = *p2;
    *p2 = n;
}
int main()
{
    int n = 10;
    int m = 20;
    swap2(&n, &m);
    printf("%d %d", n, m);
    return 0;
}

以上代码,我们通过指针修改了外部的数据,能不能算形参改变了实参呢???
不能。为什么????
因为 实参是变量的地址。变量的地址并没有发生改变。

4.2.2 场景2 指针和一维数组 语法基本通用

图片

补充几道指针计算练习题

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf("%d,%d", *(a + 1), *(ptr - 1));
    //2,5
    system("pause");
    return 0;
}

题目分析:数组名a表示数组首元素的地址,(&a+1)表示将整个数组的地址加一,(int)(&a+1)表示将(&a+1)强制类型转换为int类型。
图片.png
所以本题的结果为:
图片.png


瞿小凯
1.3k 声望593 粉丝