C语言入门:比较常用(写)的实践编程代码

1 篇文章 0 订阅

C语言入门:比较常用(写)的实践编程代码

有段时间我没有用过C语言写过东西了,但仍然还是会接触一些C语言的题目。作为本人的第一门编程语言,我想做一个本人学C语言经常写的编程代码,也希望帮助更多C语言入门小伙伴对这门语言产生更多兴趣点。

因为各位入门的同学水平看本条文时水平可能不一,我会在每个例子下面都有说明,代码旁边相应的注释也尽可能地说明。例子并没有按难度排序,所以各位可以选择性查看。(注释中的 => 代表输出结果)

下一次有机会我想分享一下C语言编写贪吃蛇程序

1.用循环取数组或字符串的长度

首先长度赋值初始量,循环条件是元素不为空,当为空时则为字符串(数组)遍历完毕,对应的循环遍历值就是长度。

#include <stdio.h>
int main(void)
{
	char * string = "helloworld"; //同价于char string[] = "helloworld" 
	int string_len; //定义一个用于存储字符串的长度变量 
	for(string_len = 0;string[string_len] != '\0';string_len++);
	//循环不需要做什么,只要变量遍历完就可以 
	printf("The String len is %d",string_len);
    // => The String len is 10
	return 0;
}

'\0’可以替换成NULL,对应的ASCII码为0,意思是什么都没有。

2.数组基本排序

比如本次采用从小到大,那么:

#include <stdio.h>
int main(void)
{
	int arr[10] = {12,32,34,21,5,23,51,21,6,52},temp;
	for(int i = 0;arr[i] != '\0';i++){
		for(int j = i + 1;arr[j] != '\0';j++){
            //arr[j] != '\0'类似例1,数组长度内遍历。
			if(arr[j] < arr[i]){
				temp = arr[j];
				arr[j] = arr[i];
				arr[i] = temp;
			}
		}
		printf("%d ",arr[i]);
        // => 5 6 12 21 21 23 32 34 43 51 52
	}
}

相当于数学上,
所 有 的 x < x ₀ 所有的 x < x₀ x<x
则x₀是最小值。

思路非常简单,就是从数组中找出最小值,通过不断的进行对比并交换值,最后拿到最小值放到最左边(这里的arr[i]),每一次相对于数组后面找出最小值,最后得出排序结果。

3.字符串转换大小写

#include <stdio.h>
#define N 10
int main(void)
{
	char string[N] = "helloworld"; 
	for(int i = 0;i < N;i++){
		string[i] -= (char)32;
		//类型转换主要是为了代码可阅读性
	}
	printf("%s",string); // => HELLOWORLD
	return 0;
}

如果是大写转小写的话,只需要把循环内的变量赋值运算换成。

string[i] += (char)32;

因为小写与大写之间ASCII码相差32,char类型就是对应的一个ASCII码。

4.指针当数组

#include <stdio.h>
#include <stdlib.h> // 必须,malloc库函数属于本头文件的 
int main(void)
{
	int * p = NULL; //空指针 
	int input_num; //用来表示需要多少个元素 
	scanf("%d",&input_num);  //假如输入5 
	p = (int *)malloc(sizeof(int) * input_num); //根据输入的值,可以理解为“申请5个int类型大小的地址单元
	//接下来就是当数组使用进行赋值 
	for(int i = 0;i < input_num;i++){
		p[i] = 6;
		printf("%d",p[i]); // => 66666
	}
	free(p); //释放指针p 
	return 0;
}

首先,指针可以当数组来使用,但是数组不可以当指针来指向新的地址。因为数组已经是固定了声明多少个类型变量的地址,而指针可以通过申请内存地址(一次申请是连续的)进行存储数据的值。

记住,指针不需要用地址的时候一定要把申请的地址空间释放了,避免造成不必要的麻烦

5.枚举类型用数值作为名称

比如,我用false,true分别代表0和1

#include <stdio.h>
int main(void)
{
	enum bool {false,true};
	enum bool foo = true;
	if(foo) printf("foo is ture"); // => foo is ture
	return 0;
}

枚举在开发用处还是挺多的,但要注意”枚举类型定义的值都是从0开始“,枚举变量名对应一个数值。

6.基本查找(数组)

这个应该是最简单的了,以数组进行举例,通过循环变量与查找变量一一对应是否符合条件,为真则可以输出查找成功。

#include<stdio.h>
int main(void)
{
	int arr[10] = {22,33,44,55,66,77,88,99,11},input_num;
	scanf("%d",&input_num);
	for(int i = 0;arr[i] != '\0';i++){
		if(arr[i] == input_num){
			printf("find input_num %d",arr[i]);
			break;
		}
	}
	return 0;
}

这里举例的是数组,也可以是其它的数据结构,这个知识点或许是入门都所知的。

7.输入流(or输出流)

程序有时候输入时换个行就把输入结束了,而我们可以利用循环和getchar函数进行达到我们以想要的符号结束。

#include <stdio.h>
#define N 100
int main(void)
{
	char string[N];
	int i = 0;
	do{
		string[i] = getchar();
		if(string[i] == '#'){
			string[i] = '\0';
			break;
		}
	}while(++i);
	printf("%s",string);
}

比如在这个程序中,以#符号作为我们结束输入的标识,但要在字符串后面加上“什么都没有”的空(NULL或’\0’)。

按照同样地思路,我们可以设计出输出流,也就是使用putchar函数。

8.递归计算

#include <stdio.h>
int sum(int n);
int main(void)
{
	int n;
	scanf("%d",&n);
	printf("total is %d",sum(n));
	return 0;
}
int sum(int n)
{
	if(n == 1) return 1;
	else return n + sum(n - 1);
}

递归顾名思义,就是自己调自己。在数据结构与算法中经常用得到,查找、求和、求阶乘等等都可以应用,感兴趣的同学可以了解一下术语:“闭包”。

9.随机生成

#include <time.h> //time库函数在此头文件中
#include <stdio.h> 
#include <stdlib.h> //srand库函数在此头文件中
int main(void)
{
	srand((unsigned int)time(NULL)); //生成种子
	int p = 1 + rand() % 6; //rand函数根据种子生成一个数,之后由于求模运算只会存在0-5的数
	printf("%d",p); // => (1~6随机数)
	return 0;
}

本例子就是一个典型的扔骰子,生成1-6的数。

10.设置控制台坐标(API)

void gotoxy(int x,int y) //TC 是有的,现在已经淘汰,自己实现
{
	//调用win API 去设置控制台的光标位置
	//1.找到控制台的这个窗口
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //windows库文件
	//2.光标的结构体
	COORD coord; //windows API定义一个结构体变量,x轴与y轴
	//3.设置坐标
	coord.X = x;
	coord.Y = y;
	//4.同步到控制台
	SetConsoleCursorPosition(handle,coord); //设置控制台光标的位置
	//windows库文件
}

通过调用这个函数,可以根据想要的控制台位置输出字符。这样也可以做一些小游戏,比如扫雷 贪吃蛇 弹弹珠等等。

11.stdlib(库)头文件三个常用的库函数

system("cls"); //清除当前控制台内容
system("pause"); //暂停当前程序
system("mode con: cols=25 lines=16"); //设置25列16行字符的控制台窗口

12.链表

typedef struct Link{
    char elem; //代表数据域
    struct Link * next; //代表指针域,指向直接后继元素
}link; //link为节点名,每个节点都是一个 link 结构体

链表是一种数据类型,当数据进行离散方式存储时用处特别大。

13.使用指针操作字符串

#include <stdio.h>
int main(void)
{
	char * p = NULL,* pp = NULL;
	char arr[10] = "**hel*lo**";
	p = pp = arr;
	while(*p){
		if(*p != '*')  *pp++ = *p;
		p++;
	}
	*pp = '\0';
	printf("%s",arr); // => hello
	return 0;
}

这个应该也是比较简单的,定义两个指针,都指向一个字符串,一个用于遍历,一个用于取目标结果,比如取非星号字符串。

14.文件复制

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE  *in, *out;	//定义两个FILE类型的指针变量
    char infile[50], outfile[50];     	//分别存放源文件和目标文件名 
    char s[256]; 				
    printf("请输入源文件名:");
    scanf("%s", infile);	//输入源文件所在路径及名称
    printf("请输入目标文件名:");
    scanf("%s", outfile);	//输入目标文件所在路径及名称
    if ((in = fopen(infile, "r")) == NULL)	//以只读方式打开指定文件
    {
        printf("打开文件%s失败\n", infile);
        exit(0);                               	//退出程序
    }
    if ((out = fopen(outfile, "w")) == NULL) 	//以只写方式打开指定文件
    {
        printf("不能建立%s文件\n", outfile);
        exit(0);                                	//退出程序
    }    
    while (fgets(s, 256, in)) 	//将in指向的文件的内容复制到out所指向的文件中
        fputs(s, out);	  
    printf("文件复制完成\n");
        //关闭文件
	fclose(in);    
	fclose(out);  

	return 0;
}

C语言文件学习的基本知识,对读取的数据进行存储到另一个文本文件上。也是和例5一样,释放地址避免不必要的浪费。

15.转化显示字符串形式二进制

#include <stdio.h>
#include <limits.h>
char * itobs(int, char *);
void show_bstr(const char *);
int main(void)
{
    char bin_str[CHAR_BIT * sizeof(int) + 1];
    int number;
    puts("Enter integers and see them in binary.");
    puts("Non-numeric input terminates program.");
    while (scanf("%d", &number) == 1)
    {
        itobs(number, bin_str);
        printf("%d is\n", number);
        show_bstr(bin_str);
        putchar('\n');
	}
    puts("Bye!");
    return 0;
}
char * itobs(int n, char * ps)
{
    int i;
    const static int size = CHAR_BIT * sizeof(int);
    for (i = size - 1; i >= 0; i--, n >>= 1)
    	ps[i] = (01 & n) + '0';
    ps[size] = '\0';
    return ps;
}

void show_bstr(const char * str)
{
    int i = 0;
    while (str[i]) /* 不是空字符 */
    {
        putchar(str[i]);
        if (++i % 4 == 0 && str[i]) putchar(' ');
    }
}

本代码是截取我最喜欢的C语言书籍《C Primer Plus》的第15章位运算的部分,本程序是用字符串模拟表示32位二进制的代码,itobs函数是以字符串模拟二进制形式存入数组,show_bstr函数则是以字符串模拟二进制输出。

16.函数声明省略参数名

#include <stdio.h>
//函数声明
void temp(int n);
// 等价
void temp(int);
int main(void)
{
	temp(0);
	//...
	return 0;
}
//函数定义
void temp(int n){ //函数定义不能省略参数名
	//...
}

或许很多朋友学习C语言的时候并没有注意一点,在函数的声明和定义上,声明是可以省略参数变量名的,但定义是不允许的,因为编译的时候编译器只会看“声明”的变量类型而不是名字。

17.引用调用

#include <stdio.h>
void change(int *);
int main(void)
{
	int x = 1;
	change(&x); //注意是x的地址
	printf("%d",x); // => 5
	return 0;
}
void change(int * x) //当形参指针x收到实参x的地址时,实质上就是指针指向这个变量
{
	*x = 5;
}

这个例子就是一个把函数参数当成关联的值,不需要通过返回值进行对主函数x内进行赋值,直接在其他的函数内进行操作。

18.字符串获取长度、复制、输出与输入的库函数,Sleep函数

以下是我个人认为会经常用得到的几个函数,并不是想把全部内容都列出来。

string.h库文件:

  1. ​ strcpy(string_1,string_2); string_2字符串拷贝至目标(字符)数组string_1中。
  2. ​ puts(string); 输出string字符串
  3. ​ strlen(string); 返回string字符串的长度。
  4. ​ gets(string); 输入字符串到string字符数组(字符串)
  5. ​ strncpy(string_1,string_2,n); string_2字符串拷贝至目标(字符)数组string_1中 (限制最大n个元素)。

windows.h库文件:

  • ​ Sleep(1000); 以1000毫秒(1秒)延迟执行接下来的代码

math.h库文件:

  1. ​ abs(x); 返回x的绝对值
  2. ​ sqrt(x); 返回x的平方根
  3. ​ pow(x,n); 返回x的n次方的值
  4. ​ ceil(x); 返回x的向上取整
  5. ​ floor(x); 返回x的向下取整
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <windows.h>
int main(void)
{
	char string[10] = "helloworld";
	int len = strlen(string);
	printf("%d\n",len); // => 10
	
	Sleep(1000);
	
	char string_2[10];
	strcpy(string_2,string); // string_2字符串的值为helloworld 
	puts(string_2); // => helloworld
	
	int temp = -1;
	temp = abs(temp);
	printf("%d",temp); // => 1
	return 0;
}

这个例子就当是随便写写,主要是能应用好这些函数即可,这样语言具有灵活性。

最后

好的,那么感谢您看到了最后。在我学C语言的时候,我对黑乎乎的控制台感觉很神奇,我好奇于为什么现在的软件是有色彩有动画的,计算机的软件设计的架构是怎么样的?当每一次例子实践,对计算机的执行逻辑感兴趣,就像人每天按照每个规则可以做到什么样的结果,是否可以对规则进行更灵活的应用。也深入想去理解整个万物构成的逻辑是什么,如同好奇于天文学。

C语言或许是每一位同学的开端,本次也希望能帮助大家发展自己兴趣爱好,精益求精于所好。祝各位同学学业有成,如果有错误,欢迎指出,谢谢。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值