初阶C语言

C语言的语句分为五类:

  • 表达式语句
  • 函数调用语句
  • 控制语句
  • 复合语句
  • 空语句

C语言是结构化的程序设计语言,存在三种结构顺序结构、选择结构、循环结构

; 再C语言表示语句的结束


分支语句

if条件控制语句:

0表示假,1表示真

当要执行多条语句时,使用代码块(用{  }括起来)。

if(表达式)
{
    语句1;
}
---------------------------

if(表达式)
{
    语句1;
}
else
{
    语句2;
}
---------------------------

if(表达式1)
{
    语句1;
}
else if(表达式2)
{
    语句2;
}
else if(表达式3)
{
    语句3;
}
else
{
    语句4;
}

switch语句

case只是一个入口,没有终止执行的能力,需要break来跳出当前的switch。

!!!没有break或者default,switch只会不断进行!!!

多个case公用一个break,可以实现同一句的执行效果。

switch允许嵌套使用。

形成良好习惯:

  • 在最后一个case后加上一个break。
  • 在每个switch最后都加一个default。

switch的条件必须是整型表达式,case必须是整型常量表达式。

  • 这里的整型包括char(存放的是ASCII码值,本质上是整型)和int。
switch (整型表达式)
{
case  整型常量表达式1:
	            语句1;
                break;
case  整型常量表达式2:
	            语句2;
                break;
case  整型常量表达式3:
	            语句3;
                break;
default:            //匹配失败
       语句;
       break;

}


switch (整型表达式)
{
case  整型常量表达式1:
case  整型常量表达式2:
case  整型常量表达式3:
	            语句1;
                break;
default:            //匹配失败
       语句;
       break;

}

循环语句

while循环
while(表达式)
{
    循环语句;
}
//表达式为真循环语句,否则停止循环

break:会跳出本层循环。是永久的终止循环。在嵌套循环中,break打破的是break所在的循环。

continue:跳过本次循环,直接去判断部分。是跳过本次循环后面的代码,直接进行下一次循环的判断。


while和getchar清理缓冲区

getchar(),是从缓冲区中读取一个字符。可以是空格、换行、回车等。

putchar(),是输出读取的字符。

int ch = 0;
while ((ch = getchar()) != EOF)
{    //EOF是'\0',在清理缓冲区时,适当替换
	putchar(ch);
}

eg:输入密码

此时,getchar从缓冲区读取的是 '\n' ,此时没有第二次输入。

 若缓冲区是一串字符,则不能用getchar直接清理。应用上述清理缓冲的循环清理。

scanf 和 printf 函数,只是在初识C语言中,对代码进行测试的输入输出语句,在以后得开发中并不重要。(不需要花费太大精力)。

通过scanf函数的%m格式控制可以指定输入域宽,输入数据域宽(列数),按此宽度截取所需数据;通过printf函数的%0格式控制符,输出数值时指定左面不使用的空位置自动填0。


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

for(初始化;判断;调整)
{
    语句;
}

初始化:初始化循环变量。

判断:循环的终止条件,判断循环的下一步操作。

调整:变更循环变量。

  1. 不可在for循环更改循环变量,防止for循环失去控制。
  2. 建议for循环控制变量的取值采用“前闭后开”的写法。

for循环的变种

省略

省略会带来一些意想不到的后果,尽量避免省略。

循环变量的初始化最好放在for循环的外面:一些编译器不支持该操作。

可以多个变量控制一个循环。


do while 循环

do while循环先执行一次在判断循环条件。

do 
{
     语句;   
}while(判断);

利用循环查找有序数列数据

int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int k = 7;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	/*for (i = 0; i < sz; i++)
	{
		if (arr[i] == k)
		{
			printf("找到了\n");
			break;
		}
	}
	if (i == sz)
	{
		printf("找不到\n");
	}*/

	//折半查找(二分查找):前提条件是数据有序
	int left = 0;
	int right = sz - 1;
	while (left<=right)//循环的终止条件:必须含有等号
	{
		int mid = (left + right) / 2;
        //mid的查找必须在循环里面
        //防止mid越界的mid定义写法:
        int mid =left+(right-left)/2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是:%d\n",mid);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到");
	}
	
	return 0;

}

折半查找就是利用循环实现的,每次查找数据减少一半。

  • 循环的终止条件:必须含有等号。
  • mid的值必须定义在循环里面。
  • mid=(left+right)/2,可能会越界(mid的最终值超过数组长度)
system("cls");//是一个库函数,可以执行系统命令
Sleep(1000);//是头文件<windows.h>里面的函数,表示系统休眠,单位是毫秒。

数组传参时传递的是数组首元素的地址


利用循环猜数字

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//#include <cstdlib>
//猜数字
//电脑产生一个随机数
// 
//猜大了
//猜小了
//直到猜对结束

#include<stdlib.h>//rand、srand函数
#include <time.h>//time函数
//猜数字菜单
void menu()
{
	printf("***********************\n");
	printf("******** 1.play *******\n");
	printf("******** 0.exit *******\n");
	printf("***********************\n");
}

void game()
{
	int guess = 0;
	//RAND_MAX;
	//1.生成随机数
	//0~99--->1~100
	int ret = rand()%100+1;//随机数在1~100之间
	//生成随机数函数
	//printf("%d\n",ret);
	
	while (1)
	{
		printf("请猜数字\n");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("猜对了\n");
			break;
		}
	}
}

int main()
{
	
	int input = 0;
	srand((unsigned int)time(NULL));//time的参数放一个空指针
	//strand设置随机数起点
	//使用time函数返回的时间戳作为随机数生成器的起点
	//不是每次使用都要设置起点,只用设置一次
	
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//printf("猜数字\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!");
			break;
		}
	} while (input);

	return 0;
}

时间戳:是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数(不考虑闰秒),用于表示一个时间点。然而,这种格式对于人类阅读并不友好,因此需要转换成可读的日期和时间格式。

利用时间戳使用随机数:

srand((unsigned int)time(NULL));
//strand设置随机数起点
//使用time函数返回的时间戳作为随机数生成器的起点
//不是每次使用都要设置起点,只用设置一次

int ret = rand();//生成随机数函数
printf("%d\n",ret);

time函数的头文件:<time.h>

rand、srand的头文件:<stdlib.h>

time函数每次使用时,最好使用空指针参数;

srand函数的参数是unsigned int 型的,利用时间戳要强制转换;


goto语句

goto语句不能跨函数跳跃,在实践中尽量避免goto语句(容易大量报错)。

goto语句常用于终止深层的嵌套循环;(break只能一层层的跳出循环)。

debug是调试版本——是程序调试的版本;

release是发布版本——是发布用户使用的版本;


函数

  • 在计算机科学中,函数是一个子程序,有一个或多个语句块组成,完成某项特定的任务,具有相对的独立性。
  • 一般有输入参数和返回值,提供对过程的封装和细节的隐藏。

一个工程里面,可以有多个.c文件,但只能有一个main函数。

函数的分类:

1、库函数:

        C语言封装的函数,方便程序员的使用。(IO函数、字符串操作函数、字符操作函数、内存操作函数、时间\日期函数等)。        

        库函数的使用必须使用 #include 包含对应的头文件。

        库函数的学习利用:https://cplusplus.com/ 或 msdn 或 cppreference.com

虚拟机:虚拟出来一台电脑。

虚拟出来的电脑(.vmk文件)。

2、自定义函数

        程序员自己设计的函数,函数的基本组成包含函数名、函数体、函数参数、返回类型。


实参和形参

实参:真是传给函数的参数。实参可以是常量、变量、表达式、函数。

形参:函数名后括号内的参数。在函数调用完后就自动销毁了。

当实参传递给形参时,形参是实参的一份拷贝--->形参的改变不会影响实参

当函数传递的参数是指针--->改变实参

px、py是指针变量,也是形参。它们存放的是啊a、b的地址。

&px、&py才是形参的地址。

*px、*py是对a、b地址的的解引用。


函数调用

1.传值调用

函数的形参和实参分别占用不同的内存块,对形参的修改不会影响实参。

2.传址调用

把函数外部创建的变量的地址传给函数参数,使得在函数内部可以直接操作函数外部的变量

C语言在C99之后引入布尔类型 bool ,在头文件#include<stdbool.h>中。

bool类型不是C语言的内置类型,本质上是0和1的封装,只占1个字节。


函数嵌套

函数可以嵌套调用,不能嵌套定义。


链式访问

把函数的返回值作为另一个函数的参数。

若函数没有返回类型(void),则没有办法实现链式访问。

main函数本质上还是有参数的:

int main(int argc, char* argv[], char* envp[])
{

}

//声明禁止传参:
int main(void)
{

}

函数声明

函数定义放在调用的后面,则需要在调用前声明。

  • 函数声明:是告诉编译器函数叫什么,参数是什么,返回类型是什么。函数声明不能决定该函数具体是否存在。
  • 函数的声明一般在函数使用之前,满足先声明后使用
  • 函数的声明一般放在头文件。
  • 函数的定义指函数的具体实现。

 将函数的声明、函数的实现、主函数分开存放,可以提高程序的可读性、实现程序模块化、方便多个程序员的协作完成。

声明和定义的分割:可以使程序以静态库的形式出售项目。

 

静态库和动态库:静态库与动态库的区别与优缺点_静态库和动态库的优缺点-CSDN博客 


函数递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值