C语言入门——通过一个实例认识c语言

 

 

目录

一.前言

二.实例

三.讲解

1.数据类型

2.变量和常量

(1).定义变量

(2).变量的分类

(3).常量

4.操作符

5.数组和字符串

(1).概念

(2).使用

6.函数

(1).scanf使用

(2).自定义函数

7.选择语句和循环语句

8.注释

9.转义字符

 


 

一.前言

这篇文章将通过一个实例对c语言里的知识点的概念及作用进行介绍简单讲解。这篇文章主要面向c语言0基础的人,看一下c语言是怎么解决和实现一个问题的。

二.实例

我将直接讲一个例子,此例子包含了大多数c语言的基础知识,后面就可以从例子中介绍c语言各个知识点的作用。此例子来自《c和指针》,我自己进行了部分修改。

问题描述:输入n个数字代表想输出的列数,如输入:3 5,就需要裁剪出第3列到第5列的字符,n不大于20,这n个数字以-1作为结尾;接着换行输入N行英文句子,最后则会将裁剪好的句子打印出来。

例子1:输入:  3 7 -1
                        hello world!

             输出:lo wo  //c语言中字符串的下标是从0开始计数的,所以h是第0列,第三列则是l

例子2:输入: 0 2 6 7 -1
                        Hello there, how are you?
                        I am fine, thank you.

             输出:Helth  //"Hel"是0到2列的字符,"th"是6到7列的字符
                              I ain  //"I a"是0到2列的字符,空格也算一个字符,"in"是6到7列的字符

例子3:输入: 4 9 12 20 -1
                        Hello there, how are you?
                        I am fine, thanks .
                        see you !
                        Bye

             输出:o ther how are
                         fine, hanks .
                        you !
 

接下来是实现的代码,可以大致浏览过后直接跳到第三部分。

代码1:

//每个输入行的后面一行是该行内容的一部分。
//输入的第1行是一串列标号,串的最后以一个负数结尾。这些列标号成对出现,说明需要打印的输入行的列的范围。
//例如,0 3 10 12 - 1表示第0列到第3列,第10列到第12列的内容将被打印。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COLS 20 //最大列数为20
#define MAX_INPUT 1000//输入的每一行句子最多有1000个字符

//函数声明
int read_col_numbers(int col_arr[]); //此函数的功能为——读取列的数,即读入例子中的0 3 10 12 -1,返回值为col_arr数组中的元素个数
void rearrange(char* output, char* const input, int n_col_arr, int const col_arr[]);
//此函数名为重新排列,即将输入的英文句子接受放入input中,再将重新排列后的结果放到要输出的output中,返回值为空

int main()
{
	//定义变量
	int n_col_arr;
	int col_arr[MAX_COLS];
	char input[MAX_INPUT] = { 0 };
	char output[MAX_INPUT] = { 0 };
	int a = strlen(output);

	//调用read_col_numbers函数,将数据0 3 10 12 -1读取到col_arr数组中,并返回数组中的个数即4,因为-1代表结束标志所以不算
	n_col_arr = read_col_numbers(col_arr);

	//将一个句子放到input中,调用rearrange函数,再打印output,再利用循环语句重复这段操作直到所有句子处理完毕
	while (gets(input) != NULL)
	{
		rearrange(output, input, n_col_arr, col_arr);
		printf("output:%s\n", output);
		memset(output, 0, strlen(output));
	}

	//执行完毕,返回
	return EXIT_SUCCESS;//EXIT_SUCCESS是<stdlib.h>中定义的符号,数值上等于0,所以也可以直接return 0;
}

//函数实现
int read_col_numbers(int col_arr[])
{
	int n = 0;//将要返回给n_col_arr的值
	char tmp_ch;//一个临时的字符型变量

	while ((scanf("%d",&col_arr[n]))!=EOF && col_arr[n]>=0 && n<=20)//当scanf读取成功并且读取的数大于0,即不为-1,并且n不大于20,循环就不会结束
	{
		n++;
	}
	if (n % 2)//如果n为奇数则进入
	{
		puts("the column numbers if not paired.");
		exit(EXIT_FAILURE);
	}
	while ((tmp_ch = getchar()) != EOF&&tmp_ch != '\n')//将-1后输入的数全部舍弃直到遇到'\n'
		;
	return n;
}

void rearrange(char* output, char* const input, int n_col_arr, int const col_arr[])
{
	int output_col = 0;
	int nchars;
	for (int i = 0; i < n_col_arr; i += 2)
	{
		nchars = col_arr[i + 1] - col_arr[i] + 1;
		if (output_col + nchars>MAX_INPUT - 1)
		{
			nchars = MAX_INPUT - 1 - output_col;
		}
		if (output_col==MAX_INPUT-1||strlen(input) <= col_arr[i])
		{
			break;
		}
		strncpy(output+output_col, input + col_arr[i], nchars);
		output_col += nchars;
	}
}

三.讲解

 

1.数据类型

我们从上面的问题开始分析,这个题简单说就是要计算机接收我们输入的数字和英文,然后按照数字去裁剪英文。那么我们是不是先要让计算机记录我们输入的数字和英文,而数字和英文显然是不一样的,所以要将他们进行分类。在c语言中,整数的数据类型称为整型,记作int;字母的数据类型称为字符型记作char。c语言中有七种默认数据类型,分别是

char           //字符数据类型(1个字节)
short          //短整型(2个字节)
int              //整形(4个字节)
long           //长整型(4个字节)
long long   //更长的整形(8个字节)
float           //单精度浮点数(4个字节)
double       //双精度浮点数(8个字节)
 
注:字节(byte)是计算机中的一个大小单位,你可能对他不熟悉但你的内存的单位G和M应该非常熟悉,我们都知道1G=1024M,但其实M还可以再分,1M=1024Kb,1Kb=1024b,b也就是字节。1字节大小为8bit,1bit就是1个二进制单位。
 
char为字符型数据,可以用来存放字符,如'a','b','&'等符号(中文一个字占两个字符)。
 
short  int  long long long均为整型,但大小不同,即他们能表示的范围也不同,short最小,longlong最大。如:short有2个字节即16bit,由于第一个二进制数要用来表示正负,0是正,1是负,所以能用来表示大小的只有15bit,所以short类型的表示范围是-2^15~2^15。
 
floatdouble为浮点型,但表示的精度不同,float精度较小,double较大。
 
除此之外c语言也支持自定义数据类型,如 结构体struct枚举enum联合体union,这里不做展开。
 

2.变量和常量

(1).定义变量

我们知道了什么是数据类型,但还没法将数据储存在计算机中,于是就需要用到变量,变量就相当于一个容器,一个变量就可以存储一个数据。在上述代码中的19~23行,数据类型后空格,再加上一个英文单词就是在定义变量,这个英文单词就是变量名,变量名只能由字母,数字或下划线组成,数字不能作为开头且该变量名不能是关键字。
int  i_1,char  _1;                正确
int  1n, char  N;                错误
int  char,char main;         错误


第20~22行变量名后带了[ ]符号,这是数组的符号,将在第5点数组和字符串中讲。

(2).变量的分类

1.局部变量
上述的19~23行的变量都是在main函数内定义的,因此都为局部变量。
局部变量的作用域是变量所在的局部范围。

2.全局变量
不在函数内定义的变量
代码2:

int i = 0;
int main()
{
	return 0;
}


如代码2,i就是一个全局变量。全局变量的作用域是整个工程。

 

(3).常量

C语言中的常量和变量的定义的形式有所差异(先不做讲解,可以稍微看看)
 
C语言中的常量分为以下以下几种:
字面常量、const 修饰的常变量、#define 定义的标识符常量、枚举常量
 
代码3:
#include <stdio.h>
//举例
enum Sex
{
 MALE,
 FEMALE,
 SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
    //字面常量演示
    3.14;//字面常量
    1000;//字面常量
    
    //const 修饰的常变量
    const float pai = 3.14f;   //这里的pai是const修饰的常变量
    pai = 5.14;//是不能直接修改的!
    
    //#define的标识符常量 演示
 #define MAX 100
    printf("max = %d\n", MAX);
    
    //枚举常量演示
    printf("%d\n", MALE);
    printf("%d\n", FEMALE);
    printf("%d\n", SECRET);
    //注:枚举常量的默认是从0开始,依次向下递增1的
    return 0;
}

4.操作符

我们定义了一个变量,但此时里面是一堆垃圾数据,所以需要我们给他赋予一个值。此时就需要用赋值操作符 = ,在变量名后加上赋值操作符就可以进行赋值,在定义时顺便赋值就称为初始化。赋值时需要注意该变量的数据类型,如char型变量需赋值字符 如:'a' '&';int型需赋值整数,如1,3;float需赋值带小数的值,如1.0,2.1。
int age = 150;
float weight = 45.5f;(f说明这个数是浮点型,如果不写编译器会默认他是double型)
char ch = 'w';(单个字符都需要写在单引号内)

注:因为char型数据底层在存储时也是用整数去表示字符的,每个字符都有对应的数值,具体可以查阅ASCII码表。如'a'在ASCII码表中对应的数为97,所以char a = 'a'; 与 char a = 97; 功能上是一样的。

至此,我们就可以将输入进去的数字和句子保存在计算机中了。

除赋值操作符之外,在上述代码中可以看到许多如:= % + - & 等符号,他们都具有不同的功能。c语言中常用的操作符有以下符号。(先不做讲解)

算术操作符
+   -   *   /   %
 
 
移位操作符
>>   <<
 
 
位操作符
&   ^   |
 
 
赋值操作符
=  +=   -=   *=   /=   &=   ^=    |=    >>=   <<=
 
 
单目操作符
!                   逻辑反操作
-                   负值
+                  正值
&                  取地址
sizeof           操作数的类型长度(以字节为单位)
~                  对一个数的二进制按位取反
--                  前置、后置--
++                前置、后置++
*                   间接访问操作符(解引用操作符)
(类型)           强制类型转换
 
 
关系操作符
>
>=
<
<=
!=                 用于测试“不相等”
==                用于测试“相等”
 
 
逻辑操作符
&&                逻辑与
||                   逻辑或

 

条件操作符
exp1 ? exp2 : exp3
 
 
逗号表达式
exp1, exp2, exp3, …expN
 
 
下标引用、函数调用和结构成员
[]   ()   .   ->
 

5.数组和字符串

(1).概念

我们现在已经可以定义变量去存储数据了,但是我们要输入进去的数字和字母都非常多,如果用一个个变量去存储将非常麻烦,所以便有了一个新的概念——数组。你会发现我在第20~22行中定义的变量后带了[ ],代表他们是数组。数组可以一次定义非常多的变量,具体个数写在[ ]里面。如 int[2] 就代表两个地址相邻的int型变量组成的数组,而char[2]就是两个地址相邻的字符型变量组合在一起,它也是数组,但由于是一串字符型数据,因此称为字符串,我们就可以用它来存放一整个句子。有了数组,在我们想申请大量数据时就不需要一个个去申请,而是能直接批量申请。

(2).使用

如我们需要5个int数据                int arr[5];
要将他们初始化需要用{}            int arr[5]={1,2,3,4,5};
访问其中的第一个并赋值给a     int a=arr[0];

 

6.函数

现在我们有了能存放大量数据的容器了,就可以开始从计算机键盘上开始输入数据,那要怎么让计算机知道我们要从键盘输入数据呢?这时就需要用一个库函数scanf

(1).scanf使用

代码4:

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    scanf("%d %d", &num1, &num2);
    printf("%d %d", num1, num2);
    return 0;
}

如代码4中,我定义了两个变量num1和num2初始化为0,调用了scanf后我就能从键盘输入两个数将他们重新赋值。除了scanf,在代码4中还有两个函数,一个是运行程序必备的main函数,所以的程序都需要它才能运行,因为他就是程序的入口。另一个是printf函数,他的作用是将num1和num2打印到屏幕上。由于篇幅有限这些函数的具体使用方法这里不做展开。

在代码1的29行中可以看到一个gets函数,他的功能与scanf类似,都是将从键盘输入的数据放到变量中。gets是从键盘获取一个句子,在这段代码中它的作用是将我输入的句子放到input数组里面。

(2).自定义函数

现在我们已经将一串数字和几串句子输入到计算机中了,于是就需要开始剪切句子。如代码1的第12和13行,我在那里定义了两个函数,

int read_col_numbers(int col_arr[]);

 void rearrange(char* output, char* const input, int n_col_arr, int const col_arr[]);

read_col_number和rearrange是他们的函数名,当我们要使用函数时就需要用它的名字才能调用它。int和void是他们的返回值的数据类型,void表示该函数无返回值。括号里面是该函数的传参。我们从代码中来解读更容易理解。
在代码1中,我在12行定义了read_col_numbers,从他的名字可以知道我将赋予它的功能是读取列的数字,也就是我要它将我从键盘输入的一串数字保存起来。而我要然他保存在我22行定义的名为col_arr的数组中,所以我需要将col_arr当做参数放在read_col_numbers的括号内,最后该函数会返回一个int型数据,所以我们可以用一个int型变量来接收它,可以看到我用的是n_col_arr。这个函数具体会返回什么取决于你在实现它的时候怎么写,我让他最终返回我输入的数的个数,那么我n_col_arr最终拿到的就是输入的数的个数。第40行后面就是实现的代码。

rearrange就是我用来负责剪切的函数,我将output,input,n_col_arr,col_arr传给rearrage函数,他就会从input中拿到句子,按col_arr中的数字对其进行裁剪,最后放回output数组中,我们就可以用printf将裁剪好的句子进行输出打印了。rearrange的实现代码在60行以下。

7.选择语句和循环语句

c语言的语句有三种,分别是顺序语句、选择语句和循环语句。(具体用法不做详解)顺序语句就是指代码会从main函数开始自上而下运行,而选择语句和循环语句就可以用来处理特殊情况。在刚刚的我说29行的gets是从键盘中获取一个句子放到input里,但这道题显然不止一个句子,这时就需要用到循环语句,可以看到在29行有一个关键词while,除他之外c语言还有for循环和do……while循环。选择语句也是为了处理一些特殊情况,如代码1的50行的if(),if是一个选择语句的关键词,()里面放条件语句,就可以做到满足条件就运行,不满足我给的条件就不运行。有了三个语句就可以处理生活中几乎所有问题了。

8.注释

从上面的代码中可以看到,每当我写中文时总是会加上/* */或//,这就是注释,加上它们之后编译器就不会你后面输入的内容当成代码。所以代码中有不需要的代码可以直接删除,也可以注释掉,或者代码中有些代码比较难懂,可以加一下注释文字

 
C语言风格的注释 /*xxxxxx*/
缺陷:不能嵌套注释
 
C++风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
 
个人建议直接用c++的注释风格
 
 

9.转义字符

在打印数据时的一些特殊操作

\?                在书写连续多个问号时使用,防止他们被解析成三字母词
 
\'                 用于表示字符常量'
 
\“                用于表示一个字符串内部的双引号
 
\\                 用于表示一个反斜杠,防止它被解释为一个转义序列符
 
\a                警告字符,蜂鸣
 
\b                退格符
 
\f                 进纸符
 
\n                换行
 
\r                 回车
 
\t                 水平制表符
 
\v                垂直制表符
 
\ddd           ddd表示1~3个八进制的数字。 如: \130 X
 
\xdd           dd表示2个十六进制数字。 如: \x30 0
 
 
至此一个将英文句子进行裁剪的问题就解决了,当然,c语言的知识远不止如此,希望同学能努力坚持认真学好c语言,c语言是基础,对后面其他专业知识的学习有巨大的影响。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值