初识C语言(三)

目录

一、选择语句

 二、循环语句

三、函数

四、数组

五、操作符(运算符)

六、常见关键字

七、总结


一、选择语句

生活中我们总会面临很多选择,比如:如果你好好学习,校招时拿一个好offer,走上人生巅峰。 如果你不学习,毕业就等于失业。这就是选择!

C语言中使用选择语句来描述现实生活中的选择。

C语言中的选择语句有:if....else 语句、if....else if....else语句(if....else的嵌套语句)、switch语句。

这里简单的说一下 if....else 语句,后期会详细的叙述选择语句。

if....else 语句:

  • 书写格式:

if(表达式){

}

else

{

}

  • 语句执行说明:

      首先判断表达式是否满足条件,满足条则为真,不满足条件则为假,表达式为真则执行if后面的语句,表达式为假则执行else后面的语句。

执行了 if 后面的语句那么 else 后面的语句就不会被执行;

执行了else 后面的语句那么 if 后面的语句就不会被执行。

注:C语言中用0表示假,非0表示真(只要不是0,不管正负都为真)!

举个例子,看一下代码的执行结果:

#include<stdio.h>
int main()
{
	int input = 0;
	printf("你要好好学习吗?(1/0):\n");
	printf("输入1表示要好好学习,输入0表示不想好好学习:");
	scanf("%d", &input);
	//C语言中一个等号是赋值操作,两个等号是判断两个数是否相等
	if (input == 1)
	{
		printf("拿一个好offer\n");
	}
	else
	{
		printf("去搬砖\n");
	}
	return 0;
}

运行结果:

输入1:

 输入0:


 二、循环语句

生活中有些事必须一直做,比如日复一日的学习。

C语言中使用循环语句来描述现实生活中的循环。

C语言中的循环语句有:while 循环、do....while循环、for循环。

这里简单的说一下while循环,后期会详细的叙述其他循环语句。

while 语句

  • 书写格式:

while(表达式)

{

}

  • 语句执行说明:
  1. 程序在进入while循环体之前先判断表达式是否满足条件。
  2. 如果满足条件则为真程序就进入循环体;程序进入循环体以后就会执行循环体中的语句,直到表达式不满足条件了就会跳出循环执行循环体后面的语句。
  3. 如果不满足条件则为假程序就跳过循环,执行循环体后面的语句。

 举个例子,看一下代码的执行结果:

#include<stdio.h>
int main()
{
	//判断写的代码是否大于500行
	//如果小于500行就输出继续敲代码,如果大于500行就跳出循环输出继续努力
	int line = 0;
	while (line <= 500)
	{
		printf("继续敲代码\n");
		line++;
	}
	printf("继续努力\n");
	return 0;
}

运行结果:

循环体中的递增或递减操作也可以直接写在while 后面的括号中,两种写法都可以。

int line = 0;
    while (line++ <= 500)
    {
        printf("继续敲代码\n");
    }
    printf("继续努力\n");


三、函数

看到函数第一时间肯定想到了数学中的函数;而在C语言中其实我们已将接触到了一些函数:比如main函数(也叫主函数)

数学中的函数举个例子f(x)=2*x+1,这个函数的功能就是计算(2倍的x) + 1的结果,给x不同的值就可以计算出不同的f(x);数学中有很多函数,每个函数都有自己独立的功能。(这里就不一一列举了)

在C语言中,把一些独立的功能也能够封装成一个独立的函数。C语言中有两种函数,一种是库函数(例如 scanf 这个函数就是库函数),另一种是用户自定义函数(自己写的函数)。

写一个函数体验一下:

两个数求和:

#include<stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    //输入
    scanf("%d %d", &num1, &num2);
    //求和
    sum = num1+num2;
    printf("sum=%d\n", sum);
    return 0;
}

运行结果:

将上面求和的功能封装成一个函数:

#include<stdio.h>
//定义函数
// Add为函数名,Add前面的int是函数返回类型
//变量x用来接收num1,变量y用来接收num2
int Add(int x, int y)
{
    int z = x + y;
    //向主函数中返回计算的结果
    return z;
}
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    //输入
    scanf("%d %d", &num1, &num2);
    //实现函数来求和
    //sum接收函数返回的值
    sum = Add(num1, num2);
    printf("sum=%d\n", sum);
    return 0;
}

运行结果:

 根据运行结果可以看到使用函数封装两个数求和可以得到相同的结果。

看到这里如果对函数还是不理解,你可以把函数想象成一个汽车工厂,一个用户给一个汽车工厂一些原材料,汽车工厂就可以对这些原材料进行加工(加工成一些汽车零件),加工完以后再对这些零件进行组装,然后组装成一辆汽车返回给用户。

这里写的函数也是一样的,给Add函数传两个参数,Add函数负责对这个两个参数求和,然后将结果返回给主函数(main函数)最后输出。

 

 有些学习C语言的朋友可能在一些书中看到将自定义函数(例如Add函数)放到main函数后面,如果将自定义函数放到main函数后面就要在main函数前面对这个进行声明,否则会报警告(可以运行)。

为什么将自定义函数放在main函数后面使用时编译器会报错?

编译器在扫描代码的时候是从上往下进行扫描,当编译器扫描到sum = Add(num1, num2);这句时,编译发现这里使用了一个Add函数,但是在这之前并没有Add函数,这个时候编译器就会报警告。所以函数必须先在前面声明才能在后面使用所以一般都是将自定义函数写在main函数之前。

 如果将自定义函数放在了main函数后面一定要在main函数前面对自定义函数进行声明。
#include<stdio.h>
//函数的声明
int Add(int x, int y);

int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    //输入
    scanf("%d %d", &num1, &num2);
    //实现函数来求和
    //sum接收函数返回的值
    sum = Add(num1, num2);
    printf("sum=%d\n", sum);
    return 0;
}
int Add(int x, int y)
{
    int z = x + y;
    //向主函数中返回计算的结果
    return z;
}

函数除了将某个功能封装之外,还有一个作用就是简化代码,看到这里可能有的朋友就会想,上面的代码中,没有用函数写的代码比用函数写的代码要少的多,用函数写的代码反而更多了,怎么能说函数使代码简化了呢!

其实并不是这样的,当我们用一个函数来实现一个功能,未来在写代码的时候如果有人想实现这个功能,就可以直接让他来调用这个函数,不用再重新去写。其实这在一定程度上完成了代码的封装,后期想实现这个功能的时候直接拿来用,不用再考虑这个功能是怎样实现的。

这里只是简单的认识一下函数,让大家知道C语言中的函数怎样写,后期会更详细的叙述C语言中的函数 。


四、数组

数组是一组相同类型元素的集合。

数组的由来:我们想在计算机中存放一个数可以直接定义一个变量,存放两个数可以定义两个变量,但是如果我们想要存放一百个或者一千个数,那我们就要定义一百个或一千个变量,这样就太麻烦了。这个时候有人就想,如果只定义一个变量就可以将这些数全部存放起来,这样就会简单很多。

数组是为了方便存放一组相同类型的数据。

1、数组定义格式:

(1)整型数组

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

  •     int 是数组类型,表示这个数组只能存放整型数据
  •    arr是数组名
  •    [10]表示这个数组最多织能存放10个数据
  •    后面的{}是对数组进行初始化,将1~9存放到arr数组中

         arr就是10个元素的整型数组

(2)存字符--字符数组

        char ch[5] = { 'a','b','c','d','e' };

        char ch1[6] = "hello";

  • hello 虽然是5个字符,但是字符串末尾隐藏了一个字符'\0',所以数组大小要定义成6

数组名是由自己来命名的,但同一个函数中不能有相同的数组名。

数组也可以不初始化(int arr[10];),但不初始化有些编译器可能会报警告,所以当你不想初始化很多数时,可以将数组初始化成0(int arr[10] = { 0 };这种初始化是不完全初始化)这里只是将数组中第一数初始化为0,其他数会默认被初始化为0,如果初始化写成:int arr[10] = { 1 };这里只是将数组中第一数初始化为1,其他数会默认被初始化为0。

2、数组的下标

当我们创建好数组后该怎样去访问它呢?---这个时候就有数组的下标。

我们可以通过每个数组中的下标访问数组中的每个元素。

数组的下标是从0开始的。

 通过下标来访问数组a中下标为3的数据:下标为3的数据是60

 也可以将数组中的所有数据全部打印出来,可以使用0~9的下标来访问数组中所有的数,可以使用循环来产生0~9这个10个数。

使用while循环打印数组中的10个数:

#include<stdio.h>
int main()
{
    int a[10] = { 10,90,50,60,77,81,99,100,66,36 };
    int i = 0;
    while (i < 10)
    {
        printf("%d ", a[i]);
        i = i + 1;
    }
    return 0;
}

运行结果:

 访问数组的时候,如果访问的下标不在定义的数组范围内,那样就会造成数据越界!


五、操作符(运算符)

C语言中包含了丰富的操作符,所以有人说:C语言是非常灵活的。

C语言甚至可以直接操作内存的数据,可以直接操作二进制位。

1、算术操作符:

 这里说一下 / 和 %

/ :除法运算

#include<stdio.h>
int main()
{
    int n = 7 / 2;
    printf("%d", n);
    return 0;
}

两边都是整型数据,所以最后得到的结果也会是一个整型数据。C语言中的整型数据会直接截断小数后的数据,只取小数点前面的数。

运行结果:

那么怎样才能输出3.5这个值呢?

这里可能有些朋友会想到将变量n定义为double类型,输出使用%lf,那么这样真的可以吗?来看一下代码执行结果:

可以看出结果并不是我们想要的。

我们就要使用另一种办法来求出3.5这个结果:将 / 两边其中的一个数写成浮点数,那么计算出来的结果就是3.5。

此时的结果就是3.5,至于3.5后面为什么会有5个0,这是因为使用 %lf 打印的数小数点默认保存了6位小数。

 % --取模(取余)

取模操作符得到的是余数

#include<stdio.h>
int main()
{
    int  n = 7 % 2; //商3 余1
    printf("%d", n);
    return 0;
}

运行结果:

取模操作符只能作用于整型,%两边必须是整数。

取模操作符的使用:

判断一个数是奇数还是偶数:

#include<stdio.h>
int main()
{
    int  n = 0;
    scanf("%d", &n);
    if (n % 2 == 1)
    {
        printf("奇数\n");
    }
    else
    {
        printf("偶数\n");
    }
    return 0;
}

运行结果:

2、移位操作符:

 移位操作符作用于一个数的二进制位!

<< 左移:

#include<stdio.h>
int main()
{
    int a = 3;
    int b = a << 1;
    printf("%d", b);
    return 0;
}

a的二进制位:0000 0000 0000 0000 0000 0000 0000 0011

<< 1为:         0000 0000 0000 0000 0000 0000 0000 0110 ---》1*2^2+2*2^1+0*2^0=6

运行结果:

3、位操作符:

这里的位指的也是二进制位

1.& 按位与对应的二进制位:有0则为0,全1才为1

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c = a & b;
    printf("%d", c);
    return 0;
}

3的二进制位:0000 0000 0000 0000 0000 0000 0000 0011

5的二进制位:0000 0000 0000 0000 0000 0000 0000 0101

进行&运算:   0000 0000 0000 0000 0000 0000 0000 0001 ---十进制的1

程序执行结果为:1

运行结果:

2.| 按位或对应的二进制位:有1则为,1,全0才为0

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c = a | b;
    printf("%d", c);
    return 0;
}

3的二进制位:0000 0000 0000 0000 0000 0000 0000 0011

5的二进制位:0000 0000 0000 0000 0000 0000 0000 0101

进行 | 运算:   0000 0000 0000 0000 0000 0000 0000 0111 ---十进制的7

程序执行结果为:7

运行结果:

3.^按位异或对应的二进制位:相同为0,相异为1

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c = a ^ b;
    printf("%d", c);
    return 0;
}

3的二进制位:0000 0000 0000 0000 0000 0000 0000 0011

5的二进制位:0000 0000 0000 0000 0000 0000 0000 0101

进行^运算:    0000 0000 0000 0000 0000 0000 0000 0110 ---十进制的6

程序执行结果为:6

运行结果:

 4、赋值操作符:

赋值操作符也叫做--复合赋值操作符

 #include<stdio.h>
int main()
{
    int a = 10;
    a = a + 4;//= 赋值
    a += 4;//+= 复合赋值符
    
    a = a - 1;
    a -= 1;
    
    a = a >> 1;
    a >>= 1;
    return 0;
}

 5、单目操作符:

在了解这几个操作符之前先来了解一下什么是单目操作符!

a+b ---有两个操作数a 和 b ,所以 + ----就是一个双目操作符;

单目操作符 ------只有一个操作数称为单目操作符。

1. !:逻辑反操作,!真--》假;!假--》真

#include<stdio.h>
int main()
{
    int a = 10;
    printf("%d", !a);
    return 0;
}

这里a为10,所以为真,那么printf语句中(!a)就为假,所以输出的结果为 0

运行结果:

2.sizeof :是一个操作符

计算的是变量或者类型所创建变量占据内存的大小,单位是字节

#include<stdio.h>
int main()
{
    int a = 10;
    //计算a变量所占内存的大小
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(int));
    return 0;
}

因为变量a的类型是int,int占4个字节,所以两个打印出来的结果都为4

运行结果:

3. ~ 按位取反:对二进制位按位取反:原来为0的变为1,原来为1的变为0。

按位取反是对内存中的补码进行取反的。

#include<stdio.h>
int main()
{
    int a = -1;
    int b = ~a;
    printf("%d\n", b);
    return 0;
}

  •     -1 是负整数
  •     负整数的二进制有原码、反码、补码、
  •     内存中存储的是二进制的补码
  •     二进制位中最高位为0表示正数,最高位为1表示负数

-1的原码:1000 0000 0000 0000 0000 0000 0000 0001

-1的反码: 1111 1111  1111  1111 1111 1111  1111  1110

-1的补码:1111 1111  1111  1111 1111 1111  1111  1111

补码按位取反:0000 0000 0000 0000 0000 0000 0000 0000

按位取反时符号位也要改变!

程序执行结果为:0

运行结果:

4.++、--

(1)前置++

#include<stdio.h>
int main()
{
    int a = 10;
    int b = ++a;//前置++,先++,后使用
    printf("a=%d b=%d\n",a, b);
    return 0;
}

先将a的值加1,然后再将a的值赋给b

运行结果:

(2)后置++

#include<stdio.h>
int main()
{
    int a = 10;
    int b = a++;//后置++,先使用,后++
    printf("a=%d b=%d\n", a, b);
    return 0;
}

先将a的值赋给b,然后再将a的值加1

运行结果:

(3)前置--

#include<stdio.h>
int main()
{
    int a = 10;
    int b = --a;//前置--,先--,后使用
    printf("a=%d b=%d\n",a, b);
    return 0;
}

先将a的值减1,然后再将a的值赋给b

运行结果:

(4)后置--

#include<stdio.h>
int main()
{
    int a = 10;
    int b = a--;//后置--,先使用,后--
    printf("a=%d b=%d\n", a, b);
    return 0;
}

先将a的值赋给b,然后再将a的值减1

运行结果:

5.(类型)--强制类型转换

把一个浮点型数据转换为整型,如果直接定义为整型编译器会报警告:

为了避免编译器报错,可是使用强制类型转换将浮点型转换为整型:

#include<stdio.h>
int main()
{
    int a = (int)3.14;
    printf("%d\n", a);
    return 0;
}

运行结果:

6、关系操作符

这里强调一点:C语言中 = 是赋值,==是用于判断是否相等

7、逻辑操作符

(1)&& 逻辑与---并且

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    if ((a == 3) && (b == 3))
    {
        printf("hehe\n");
    }
    return 0;
}

&& 两边的条件同时为真时才会进入if语句,所以程序运行以后不会打印任何东西

运行结果:

(2) ||   逻辑或---或者

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    if ((a == 3) || (b == 3))
    {
        printf("hehe\n");
    }
    return 0;
}

|| 两边的条件只要有一个为真就会进入if语句,所以程序运行以后会打印hehe。

运行结果:

8、条件操作符(三目操作符):

 条件操作符可以简化 if 语句

exp---表达式

表达式1的结果为真,就是表达式2,表达式2为整个表达式的结果(不用计算表达式3);

表达式1的结果为假,就是表达式3,表达式3为整个表达式的结果(不用计算表达式2);

  • 使用 if....else 语句

  • 使用条件操作符:

 #include<stdio.h>
int main()
{
    int a = 0;
    int b = 0;
    int max = 0;
    scanf("%d %d", &a, &b);
    max = a > b ? a : b;
    //打印
    printf("%d\n", max);
    return 0;
}

运行结果:

9、逗号表达式:

逗号表达式会从左向右依次计算,整个逗号表达式的结果是最后一个表达式的结果

 #include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c= 10;
    int d = (a + 2, b = a - 3, c = b + 4);
    printf("%d\n", d);
    return 0;
}

a+2 这个表达式没有产生任何效果,所以这个表达式没什么用。再计算 b = a - 3 = 3 - 3 = 0 ,再计算 c = b + 4 = 0 + 4 = 4,所以程序执行的结果为:4

运行结果:

10、下标引用、函数调用和结构体成员

(1) [ ] ----下标引用操作符

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

对于[ ]它有两个操作数,分别为arr数组名和方括号中的10。

(2)() -----函数调用操作符

因为函数的参数是不确定的,一个函数可以没有参数,也可以有多个参数,所以函数调用操作符至少有一个操作数。

这里只是简单的讲述了一些操作符让大家对操作符有一个了解,有些操作符也没有讲到,后期会更详细的讲解这些操作符。


六、常见关键字

 atuo 关键字

auto只能用来修饰局部变量;所有的局部变量默认都是auto修饰的。

因为使用auto关键字修饰的变量会自动创建自动销毁,而局部变量本身就有这样的特点,进入局部变量的范围它就开始创建,出了局部变量的范围它就自动销毁了。所以auto关键字一般省略不写(写不写效果都一样)。

register关键字:

register修饰变量是将所修饰的变量放入CPU寄存区中从而达到提高效率的目的;

CPU实际在读取数据时不考虑CPU内的寄存器或其他暂时的情况,CPU能够直接访问内存,若数据没有加载到内存中,直接将数据或程序都存放在硬盘中,当CPU想访问数据时必须访问外设,而外设速度很慢。

离CPU越近的存储单元,效率越高;离CPU越远的存储单元,效率越低;

缓存:CPU访问数据的时候,以最小的成本达到最高的效率;

寄存器的本质是在硬件层面上提高计算机的运算效率(因为不需要从内存中读取数据)。

register一般修饰局部变量(修饰全局变量会导致CPU寄存器被长时间占用);

使用register修饰的变量会高频的被读取,请不要大量使用,因为寄存器的数量是有限的;

  • register修饰的变量可以被写入

  • 使用register修饰的变量不能访问该变量的地址(因为register修饰的变量已经存放在了寄存器中,地址是内存相关的概念);

#include<stdio.h>

int main()

{

register int a = 100;

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

a = 200;

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

printf("&a=%p\n", &a);

return 0;

}

运行结果:

register关键字只是起到一个建议的作用,因为现在的编译器已经很智能了,能够进行比人更好的代码优化。 早期编译器需要人为指定register,来进行手动优化,现在不需要了。

 typedefine 关键字 ---可以使变量换个名字

#include<stdio.h>
int main()
{
    double num1= 3.14;
    //使用typedefine关键字将double改名为dou
    typedef double dou;
    dou num2 = 1.414;
    printf("%lf\n", num1);
    printf("%lf\n", num2);
    return 0;
}

运行结果:

 根据运行结果可以看出使用 typedefine 关键字改名后的变量只是改变了它的变量名,使用的时候是没什么变化的。

typedefine 关键字还可以修改函数名,结构体名。这里就不详细的说明了,之后这些用法都会详细的讲述。

这里对关键字做一些简单的介绍,后期会详细介绍剩下的关键字。


七、总结

初识C语言这个系列只是让大家先了解一下C语言,很多内容都没有详细的叙述。后面每个知识点都会详细的讲述。

编程语言的学习是一个枯燥的过程,但是在这个枯燥的过程中也会发现很多的快乐。

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇湘夜雨.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值