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库文件:
- strcpy(string_1,string_2); string_2字符串拷贝至目标(字符)数组string_1中。
- puts(string); 输出string字符串
- strlen(string); 返回string字符串的长度。
- gets(string); 输入字符串到string字符数组(字符串)
- strncpy(string_1,string_2,n); string_2字符串拷贝至目标(字符)数组string_1中 (限制最大n个元素)。
windows.h库文件:
- Sleep(1000); 以1000毫秒(1秒)延迟执行接下来的代码
math.h库文件:
- abs(x); 返回x的绝对值
- sqrt(x); 返回x的平方根
- pow(x,n); 返回x的n次方的值
- ceil(x); 返回x的向上取整
- 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语言或许是每一位同学的开端,本次也希望能帮助大家发展自己兴趣爱好,精益求精于所好。祝各位同学学业有成,如果有错误,欢迎指出,谢谢。