<C语言>初识C语言(二)

循环语句

while循环

在现实生活中,我们有时候不得不在同一件事情上需要反复地去完成,这个在C语言程序可以使用while语句去实现循环。

//while 语法结构
while(表达式)	//只要表达式非0便继续执行
{
    循环语句;
}

while流程图:

image-20221210092033593

举个例子:在屏幕上打印1~5个数字

#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 5)
	{
		printf("%d ", i);
		i = i + 1;
	}
	return 0;
}

运行结果:

image-20221210090309586

do…while循环

//do...while语法结构
do
{
    循环语句;
}while(表达式);

相比较while,do…while循环比while循环多执行一次

也就是说,do…while语句最少执行一次,而while语句可以一次也不执行

一般很少使用

do…while流程图:
在这里插入图片描述
举个例子:

#include <stdio.h>
int main()
{
	int i = 5;
	do
	{
		printf("%d\n", i);
		i++;
	} while (i < 10);
	return 0;
}

运行结果:

image-20221210093130165

当去掉 i++;时,语句就会循环打印5,没法停止。因此,在循环语句中一定要设置好终止条件!

for循环

//for语法结构
for (表达式1; 表达式2; 表达式3)
{
	循环语句;
}

表达式1为初始化部分,用于初始化循环变量

表达式2为条件判断部分,用于判断循环时候终止

表达式3为调整部分,用于循环条件的调整。

此循环常使用

for流程图:

image-20221210094430208

举个例子:在屏幕上打印1~5个数字

#include <stdio.h>
int main()
{
	for (int i = 1; i <= 5; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

运行结果:

对比while循环:

for循环的风格更胜一筹;for循环使用的频率也最高。

以上三种循环也可以嵌套循环,往后慢慢介绍

函数

什么是函数?

其实我们在数学当中介绍过函数

比如:f(x)=2*x+1

也就是说,不同的x有不同的结果

其实相较于C语言函数来说,跟数学中的函数是非常相似的

举个例子:计算两数相加

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0;
}
//上述代码,写成函数如下:
#include <stdio.h>
int Add(int x, int y)	//Add是函数名,int x,int y 是函数参数(形参),int是返回类型
{
    int z = x + y;	//函数体
    return z;
}
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = Add(num1, num2);
    printf("sum = %d\n", sum);
    return 0;
}

在现实生活中,函数相当于一个工厂,我们给它提供原料,然后让它制造出我们想要的产品
在这里插入图片描述在这里插入图片描述

函数的特点就是简化代码,代码复用。

数组

C语言中给了数组的定义:一组相同类型元素的集合

数组定义

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素

数组下标

C语言规定:数组的每个元素都有一个下标且下标是从0开始

int arr[10] = {0};	//不完全初始化,只初始化第一个元素,其他未初始化的元素默认初始化为0
//如果数组10个元素,下标的范围是0-9

在这里插入图片描述

数组的使用

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    for (i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

运行结果:
在这里插入图片描述

操作符

下面就简单介绍一些常用的为主,后期用到别的操作符会特别注明

算术操作符

+-*/%	模除

举例:

#include <stdio.h>
int main()
{
	int a = 6, b = 4;
	float x = 6.0, y = 4.0;
	printf("%d\n", a + b);
	printf("%d\n", a - b);
	printf("%d\n", a * b);
	printf("%d\n", a / b);
	printf("%d\n", a % b);
	printf("%f\n", x / y);
	return 0;
}

运行结果:

image-20221210164240212

根据结果来看 + - * 跟我们平常计算结果是一样的

我们接下来先说一下关于 / % 的问题:

% 模除,规定模除的两边数据类型都为整型,取余数,例如 6 % 4,商1余2

/ 除,若除号两边都为整数,那么执行的是整数除法,例如上面的例子 6 / 4 = 1,不进行四舍五入,若至少有一个操作数的数据类型为浮点数,那么执行的就是浮点数除法,例如 6.0 / 4,6 / 4.0,6.0 / 4.0

移位操作符

<<	>>

位操作符

&	^	|

赋值操作符

=	
//以下都是复合赋值符
+=
-=	
*=
/=	
&=
^=	
|=	
>>=	
<<=

举例:

#include <stdio.h>
int main()
{
	int a = 0, b = 3, c = 2;
	a = 20;
	printf("%d\n", a );
	c += b;	//等同于 c = c + b;  其他类似
	printf("%d\n", c);
	return 0;
}

运行结果:

image-20221210165453157

单目操作符

!           逻辑反操作 假变真,真变假	逻辑非
-           负值
+           正值
&           取地址
sizeof      操作数的类型长度(以字节为单位),不是函数,是操作符
~           对一个数的二进制按位取反
--          前置、后置--
++          前置、后置++
*           间接访问操作符(解引用操作符)
(类型)       强制类型转换

有一个操作数的叫单目操作符,有两个操作数叫双目操作符。

在C语言中,非零为真,零为假

举例:(关于前置后置+ + - -)

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

运行结果:

image-20221210170951598

从a++很明显就可以看出,后置++,先赋值,后++

同理 ++前置,先++,后赋值,无论是后置还是前置- - , 都同+ +

关系操作符

>
>=
<
<=
!=      用于测试“不相等”
==      用于测试“相等”

用来比较大小或者是否相等。

逻辑操作符

&&     逻辑与,并且
||     逻辑或,或者

image-20221210175655242

条件操作符

三目操作符

exp1 ? exp2 : exp3	//exp1为真执行exp2,否则执行exp3

逗号表达式

exp1, exp2, exp3, …expN

特点:从左向右依次计算,整个表达式的结果是最后一个表达式的结果

例如:

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

运行结果:

image-20221210180641662

下标引用,函数调用和结构成员

[] () . ->

举例:

//下标引用操作符
int arr[3] = {0};
arr[1] = 2;	//明确给下标为1的数赋值
//函数调用操作符
int add(int x,int y)
{
	return x + y;
}
int main()
{
    int c = Add(2,3);	//()是函数调用操作符,操作数是:Add,2,3
    printf("%d\n",c);
    return 0;
}

常见关键字

C语言提供了丰富的关键字,这些关键字都是C语言本身预先设定的,用户自己是不能创造关键字的。

变量名也不是关键字

auto  break   case  char  const   continue  default  do   double else  enum   
extern float  for   goto  if   int   long  register    return   short  signed
sizeof   static struct  switch  typedef union  unsigned   void  volatile  while

以上关键字有一部分在初识C语言(一)有所涉猎,可移步去《初识C语言(一)》重新预习,本文章不再详细叙述。

  1. auto 自动——自动变量

局部变量都是自动创建,自动销毁的,所以我们平时使用的局部变量都是由 auto 修饰,因此没有特殊情况的时候可以不用写出 auto。

int main()
{
    auto int a = 10;
    //等同于
    int a = 10;
}
  1. 循环

break 用于循环语句,可终止循环

continue 也是用于循环,也可以终止循环,与 break 不同

同时用于循环的还有关键字 case,default,do…while,for

default其实就是一个默认选项

  1. 类型

    char short int long longlong float double 
    signed	//有符号
    unsigned	//无符号
    typedef	//类型重定义,不是类型,可以给类型换一个别的名字
    void	//空类型,无类型
    

typedef关键字

typedef //类型重定义,不是类型,可以给类型换一个别的名字

例如:

int main()
{
    unsigned int num;	//很长
}
我们可以写成以下形式
typedef unsigned int uint;
int main()
{
    uint num;	//同 unsigned int num;
}
  1. 修饰变量,指针

const 修饰变量,指针

static(静态) 修饰变量

static关键字

在C语言中: static是用来修饰变量和函数的

修饰局部变量-称为静态局部变量

修饰全局变量-称为静态全局变量

修饰函数-称为静态函数

#include <stdio.h>
void test()
{
    int i = 0;
    i++;
    printf("%d ", i);
}
int main()
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        test();
    }
    return 0;
}

运行结果:

image-20221220121739409

当我们改为以下格式:

#include <stdio.h>
void test()
{
    static int i = 1;
    i++;
    printf("%d ", i);
}
int main()
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        test();
    }
    return 0;
}

运行结果:

image-20221220121904339

这是因为普通的局部变量是放在内存的栈区上的,进入局部范围,变量创建,出了局部范围变量销毁。
而当static修饰局部变量的时候,局部变量是在静态区开辟空间的,这时的局部变量,出了作用域变量不销毁,下次进去作用域,使用的是上一次遗留的数据。(因为 static 关键字改变了存储位置,由栈区->静态区,使得变量的生命周期发生了改变,直到程序结束后才会销毁)

一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用

全局变量是具有外部链接属性的,如果全局变量被static修饰,外部链接属性就变成了内部链接属性。其他源文件就没法在通过链接找到这个符号的

  1. 选择(分支)

if,else,goto,switch

case,default等关键字也可用于分支

  1. 自定义类型

enum—— 枚举,在《初识C语言(一)》有所涉猎

struct——结构体

union——联合体,共用体

  1. extern 用来声明外部符号
//源.cpp
#include <stdio.h>
extern int g_val;
int main()
{
    printf("%d\n", g_val);
    return 0;
}
//源1.cpp
int g_val = 2022;

运行结果:

image-20221220125708775

  1. register 寄存器关键字

数据在计算机中可存放在 内存,硬盘,高速缓存,寄存器

image-20221220111753460

  1. return 一般用于函数的返回

  2. sizeof 操作符

  3. volatile,后期详细叙述

指针

内存

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,该编号被称为该内存单元的地址。

image-20221220134755899

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的.

同时,我们把编号也叫做指针。

换句话说,指针就是地址,而指针变量就是存储地址的变量

为使用指针,C语言提供了一对特殊设计的运算符。为了找到变量的地址,可以使用 &(取地址)运算符。如果x是变量,那么&x就是x在内存中的地址。

为了获得对指针所指向对象的访问,可以使用 * (间接寻址)运算符。如果p是指针,那么*p表示p当前指向的对象。

取出变量地址如下:

#include <stdio.h>
int main()
{
    int num = 10;
    &num;//取出num的地址,这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
    printf("%p\n", &num);//打印地址,%p是以地址的形式打印
    return 0;
}

运行结果:

image-20221220163822192

取出地址后,该如何存储呢,代码如下:

#include <stdio.h>
int main()
{
    int num = 10;	//占 4 个字节
    int* p;	//int* 整体是一个类型 p为整形指针类型
    p = &num;
    return 0;
}
//int 说明 p 指向的对象是int类型
// * 说明 p 是指针变量

image-20221220165513134

以整形指针举例,可以推广到其他类型:

#include <stdio.h>
int main()
{
    int num = 10;
    int* p = &num;

    char ch = 'w';
    char* pc = &ch;
    return 0;
}

指针变量的大小

指针变量是用来存放地址的

所以指针变量的大小取决于存储一个地址需要多大的空间

#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(long*));
    printf("%d\n", sizeof(long long*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(double*));
    return 0;
}

运行结果:

image-20221221112756921

指针变量的大小取决于地址的大小

32位平台下地址是32个bit位(即4个字节)

64位平台下地址是64个bit位(即8个字节)

补充个小知识:

sizeof 计算的结构是无符号整数,对应的打印格式是 %zu

点到为止,后期会详细补充。

结构体

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

结构体通常用来描述复杂对象。

比如我们要描述一个学生,我们要知道他的姓名,年龄,性别,身高,体重,班级,学号等信息。如果说是一台电脑,我们要知道他的品牌,类型,内存,功能,硬盘,价格等信息。这些通常很复杂,不能单一的去描述,因此,我们这里要用到结构体。

下面以学生为例,我们需要知道他的姓名,年龄,成绩

#include <stdio.h>
struct Stu
{
    char name[25];
    int age;
    float score;
};
void Print(struct Stu* ps)
{
    printf("%s %d %f\n", (*ps).name, (*ps).age, (*ps).score);
    //结构体指针->结构体成员
    printf("%s %d %f\n", ps->name, ps->age, ps->score);
}
int main()
{
    struct Stu s1 = { "艾莜薇",19,95.5f };
    struct Stu s2 = { "哎呦喂",20,96.5f };
	//结构体变量 . 结构体成员
    printf("%s %d %f\n", s1.name, s1.age, s1.score);
    Print(&s2);
    return 0;
}

运行结果:

image-20221222165930275

在这里,我们用到了一个操作符 . 和 —>

格式:结构体变量 . 结构体成员

格式:结构体指针->结构体成员

我们已经知道了怎么输出,那我们该怎么输入呢,参考以下代码

#include <stdio.h>
struct Stu
{
    char name[25];
    int age;
    float score;
};
int main()
{
    struct Stu s3 = {  };

    printf("请输入学生姓名,年龄,成绩\n");
    scanf("%s %d %f", s3.name, &(s3.age), &(s3.score));
    //name 是个数组,数组名本来就是地址,因此不需要取地址符
    printf("请输出学生姓名,年龄,成绩\n");
    printf("%s %d %f\n", s3.name, s3.age, s3.score);
    return 0;
}

运行结果:

image-20221222170920676

为什么我们输入的成绩与输出的成绩不一样呢?

那是因为浮点数在内存中是无法精确保存的。

点到为止,后续慢慢补充。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

艾莜薇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值