【初阶三】认识C语言—下

1.函数

函数就像一个工厂,通过输入原料(传递参数),在工厂(函数)内加工(代码执行)后返回一个成品(return一个值)

  • 我们使用的scanf和printf都是C语言的库函数(C语言提供的内部函数,需要引用头文件才能使用)
  • 还有一种函数是我们自己实现的函数,接下来举例说明

这是一个求a+b的和并打印的代码,在main函数中实现:

在这里插入图片描述

这是使用自己实现的函数求a+b的和并打印:
请添加图片描述
代码进行优化,不用定义变量num直接返回a+b也可以达到一样的效果:
请添加图片描述

形式参数和实际参数:实际上是将实际参数的值临时拷贝一份给形式参数,二者除了值相同以外,没有任何联系,他们拥有不同的存储空间,所以形参的改变对实参没有影响

大家可能有一个疑问,自己实现的函数add比main函数内实现更加繁琐,为什么还要使用自己的函数呢?
1.在main函数外实现函数会使代码层次分明,更易读
2.当我们以后实现一个大型项目时,一个功能难免会被多次使用,这时只要将这个功能写成自己的函数,就可以通过调用函数来使用这个功能,比每次都写一遍更方便快捷

2.数组

当我们想要存储100个数据时,我们不可能定义100个变量,所以C语言提供了数组
数组即为一组相同类型元素的集合,我们可以将所有相同类型的数据存储在数组里

请添加图片描述

数组规定每个元素都拥有下标,下标从0开始计数,可以通过下标来访问数组

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//存储了10个整形元素的数组
//             0 1 2 3 4 5 6 7 8 9   //整型1的下标是0,整型2的下标为1,以此类推

通过下标来访问数组:
在这里插入图片描述

3.操作符

3.1算数操作符

在这里插入图片描述

分别时加、减、乘、除、取余

加减乘与数学中一样,但乘的符号换成了 *
重点讲解 除 和 取余 两种算术操作符
C语言中除法分为整数除法和浮点数除法

整数除法:


#include<stdio.h>

int main()
{
	int a = 7;
	int b = 2;
	int c = a / b;//整数除法中除号两边的变量必须都为整型
	printf("%d", c);//结果为3,而不是3.5,是因为C语言的除法是整除之后得到商
	return 0;
}

浮点数除法:

int main()
{
	int a = 7/2;
	printf("%d\n", a);//这里的结果为3,因为它是整数除法
	printf("%lf\n", 7.0 / 2);//结果为3.500000
	printf("%lf\n", 7 / 2.0);//结果为3.500000
	printf("%lf\n", 7.0 / 2.0);//结果为3.500000
	return 0;

只要除号左右两边至少有一个为浮点型,那它就是浮点数除法
printf中的%lf表示要打印float类型的数据(精读到小数点后6位)

取余:

#include<stdio.h>

int main()
{
	int a = 7;
	int b = 4;
	int c = a % b;
	printf("%d", c);//这里得到的结果为3,1来自于7除4得1余3.
	return 0;
}

操作符%左右两边必须为整形

3.2移位操作符和位操作符

在这里插入图片描述
这里移位操作符和位操作符都是操作的二进制位,>>是右移操作符,<<是左移操作符

#include<stdio.h>

int main()
{
	int a = 10;//10的二进制表示是00001010,补码是00001010
	a = a << 1;//补码左移1位后是00010100,右边自动补0.
	printf("%d", a);//a的二进制位左移后值变了,十进制对应二进制0010100是20,所以打印结果20
	return 0;
}

&叫做按位与, |叫按位或,^叫按位异或

#include<stdio.h>

int main()
{
	int a = 10;//a的二进制00001010,补码是00001010
	int b = 5; //b的二进制00000010,补码是00000010
	int c = a & b;//补码按位与,都是1才是1,得00000010
	int e = a | b;//补码按位或,都是0才是0,得00001010
	int d = a ^ b;//补码按位异或,相同为0,相异为1,得:00001000
	return 0;
	}

3.3赋值操作符

赋值操作符很多,但用法相近,它们的涵义是将等号右边的值赋值给等号左边的变量

在这里插入图片描述

先拿 = 举例:
在这里插入图片描述

上面这段代码会把两段话都打印出来,因为这里的if判断内容是赋值而不是相等,只是一个容易忽视的错误
=是赋值运算符,==才是比较

更改之后就可以看到如下结果:

在这里插入图片描述
再用 += 举例:

#include<stdio.h>

int main()
{
	int a = 1;
	int b = 2;
	a += 1;//此代码等同于a = a + 1
	a += b;//次代码等同于a = a + b
	return 0;
}

这时再去理解其他操作符就很好理解了

3.4单目操作符

这些操作符只作用在一个操作数上,比如我们的算术操作符 / ,它作用在除号两边的两个操作数,所以它不是单目操作符
这些单目操作符中,我们把 & 和 * 操作符放到后面的章节详细讲解

在这里插入图片描述

在这里插入图片描述

逻辑反操作符 ! ,在一个变量前面加上一个逻辑反!,它的逻辑就会颠倒

++和–可以作用在操作数的左边或者右边,两种形式表达的意思是不相同的,例:

#include<stdio.h>
int main()
{
	int a = 1;
	printf("%d\n", a++);//当++放在操作数右边时,是先使用操作数本来的值再把操作数+1.打印结果为1
	printf("%d\n", a);//这个地方,a在前面已经自增过1了,所以打印2
	int b = 2;
	printf("%d\n", ++b);//当++放在操作数左边时,是先把操作数的值+1再使用+1后的值.打印3
	return 0;
}

目操作符(类型),指一个括号里面放一个类型,比如(int),(char),它的作用是强制类型转换,例:

#include<stdio.h>

int main()
{
	int a = 5;
	int b = 2;
	float c = (float)a / b;//我们说当除号左右至少都一个操作数为浮点型,那就是浮点型除法.
	int d = a / b;
	printf("%lf\n", c);//强制类型转换a的int类型为float类型后,a被当作浮点型,所以进行浮点型除法
	printf("%d\n", d);//这里没有强制类型转换,为整型除法
	return 0;
}

3.5关系操作符

在这里插入图片描述
C语言中的大于等于用的是>=,小于等于用<=
一个=是用来赋值的
双等号==才是用于判断是否相同的

3.6条件操作符

它的意思是如果exp1的逻辑为真,就返回exp2的值,如果exp1的逻辑为假

exp1 ? exp2 : exp3

例:

#include<stdio.h>

int main()
{
	int a = 5;
	int b = 2;
	int c = a > b ? 10 : 5;//这里a大于b为真,所以我们执行冒号前面的值,打印10
	printf("%d", c);
	return 0;
}

3.7逗号表达式

int main()
{
	int a = 3;
	int b = 2;
	int c = 5;
    //逗号表达式,是从左向右依次计算的,逗号表达式的结果是最后一个表达式的结果
	int d = (a+=3, b=5, c=a+b, c-4);
	     //  a=6   b=5  c=11    7
	printf("%d\n", d);//d的值为最后一个表达式的值为7
	printf("%d\n", a);//我们再把a,b,c的值打印出来,会发现它们不是本来的3,2,5了,而是在逗号表达式
	printf("%d\n", b);//中经过计算后重新得到的数
	printf("%d\n", c);
	return 0;
}

4.常见关键字

请添加图片描述

4.1关键字typedef

typedef 是类型定义,这里理解为类型重命名

#include<stdio.h>

typedef unsigned int unit;//将unsigned int 重命名为unit, 所以uit也是一个类型名

int main()
{
	//观察num1和num2,这两个变量的类型是一样的,相当于把unsigned int改了一个名字
	unsigned int num1 = 0;//改名后,改名前的类型也可以使用
	unit num2 = 0;
	return 0;
}

现在学习到的int,char等类型长度比较短,使用typedef可能没有那么明显的好处,但是后期我们接触顺序表和链表后,typedef的作用就能体现出来了

4.2 关键字static

static是用来修饰变量和函数的

  • 修饰局部变量:称为静态局部变量
  • 修饰全局变量:称为静态全局变量
  • 修饰函数:称为静态函数

请添加图片描述

#include<stdio.h>

void test()test函数中创建的变量a是局部变量,所以它在我们调用一次函数结束后会把内存还给系统销毁
{
    int a = 5;
    printf("%d ", a);
	a++;
}

int main()
{
	int i = 0;
	while (i < 10)//调用10次test函数
	{           
		test();//每次调用test函数进来就重新定义一个变量a=5,这时的a和前一次调用的a没有关系,因为上一个a已被销毁
		i++;
	}

	return 0;
}

这段代码不断打印5,因为调用一次test函数后a就被销毁了,a++后a变成6后的值不会保存起来,下一次调用函数时a的初始值还是5

我们再来看看用static修饰a后会出现什么变化:

#include<stdio.h>
![请添加图片描述](https://i-blog.csdnimg.cn/direct/276cde04a11644939400c85eff97737f.jpeg)

void test()
{
    static int a = 5;//static修饰a后,a就不在栈区了,a就被存放在静态区了!
    printf("%d ", a);//打印5,6,7......
	a++;
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

5. define定义常宏

define定义宏和我们之前的定义常量有一点相似

//define定义宏
#define ADD(x, y) ((x)+(y))//Add后面括号里的x和y为参数,后面的((x)+(y))叫做宏的实现体
#include <stdio.h>

int main()
{
    int sum = ADD(2, 3);//遇见Add()时就会自动把Add和里面的变量替换为后面的宏的实现体
    printf("sum = %d\n", sum);
    
    sum = 10*ADD(2, 3);//遇见Add()时就会自动把Add和里面的变量替换为后面的宏的实现体
    printf("sum = %d\n", sum);
    
    return 0;
}

6.指针

6.1内存

C语言中指针就是用来访问内存的,内存是电脑上特别重要的存储器,计算机中的程序都是在内存中运行的(一个比特位对应一个二进制位也就是存放一个二进制数)
为了有效地使用内存,内存被划分成一个个小内存单元,每个内存单元的大小是1个字节
为了能够有效的访问到内存的每个单元,就给内存单元进行编号,这些编号被称为该内存单元的地址
所以C语言引出了指针和地址的概念,方便我们寻找变量在内存中的位置,变量是创建内存中的(在内存中分配空间),所以变量也是有地址的

请添加图片描述

在计算机中有地址线(物理的电线),它将高低电平信号转换为数字信号1和0(二进制信息),我们的32位电脑上有32根地址线,每根地址线传达的数字信息要么为0要么为1,所以我们的一个内存单元(一个字节)可以存储二进制00000000000000000000000000000000到11111111111111111111111111111111内的任何数据,转换为10进制也就是存储到0到4,294,967,296

6.2取地址操作符&

#include <stdio.h>

int main()
{
	int num = 10;
	&num;//取出num的地址
    //注:这里num的地址大小是4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
    printf("%p\n", &num);//打印地址,%p是以地址的形式打印
	return 0;
}
char temp = 'w'char* p = &temp;//p是char类型的指针,可以存放变量temp的地址
*p = 'z'//*p是解引用,解引用后就是temp变量,可以赋值成z
//判断自己是多少位的机器
//观察指针变量的大小
#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
    printf("%d\n", sizeof(char *));
    printf("%d\n", sizeof(short *));
    printf("%d\n", sizeof(int *));
    printf("%d\n", sizeof(double *));
    return 0;
}

7.结构体

结构体关键字:struct

结构体使得C语言有能力描述复杂类型,比如我们想描述学生,学生包含了名字、年龄、性别、学号这几项信息,如果我们用传统的方法是不能解决的,这里就能使用结构体来描述了:

struct Student
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]//学号
};

结构体初始化:

struct Student
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]; //学号
};

int main()
{
    //初始化结构体后,name里面放入的是张三,age里面为20,sex为男,id是20180101,中间用逗号隔开.
    struct Student s = { "张三", 20, "男", "20180101" };//这里定义结构体变量名为s
   
    printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id); //.为结构成员访问操作符,是结构体成员的访问
    
    struct Student* ps = &s;
    printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps -> id);//->操作符相当于结构体中的解引用操作

	return 0;
}

我们还可以在程序中定义多个结构体:

#include<stdio.h>

struct Student
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
};

struct Book//描述一本书
{
	char name[20];//书名
	char author[20];//作者
	float price;//价格
};

int main()
{
	struct Student s1 = { "张三", 20, "男" };
	struct Student s2 = { "李四", 20, "男" };
	struct Student s3 = { "王五", 20, "男" };

	struct Book b = { "《STL源码剖析》", "Hou Jie", 79.0f };
	printf("%s %s %f\n", b.name, b.author, b.price);

	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值