以前有了解一点点Java和Python,最近开始自学C语言,做此博客来记录我的学习过程。如有不对不妥之处,请大家斧正。
什么是C语言呢,百科是这样介绍的:C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。
总之呢,C语言是一位老前辈了,它几乎所有编程语言的先驱与灵感的来源,Perl,PHP,Python和Ruby都是用它写的,同样什么Microsoft Windows,Mac OS X,还有GNU/Linu这些操作系统,都是靠它写出来的。所以他的重要性不言而喻了。
下面开始我的记录:
1 #include <stdio.h>
2 int main()
3 {
4 return 0;
5 }
所有的 C 语言程序都需要包含 main() 函数。 代码从 main() 函数开始执行。
stdio.h 是一个头文件 (标准输入输出头文件) , #include 是一个预处理命令,用来引入头文件。 当编译器遇到 printf() 函数时,如果没有找到 stdio.h 头文件,会发生编译错误。
return 0; 语句用于表示退出程序。
printf() 用于格式化输出到屏幕。printf() 函数在 “stdio.h” 头文件中声明。
在实际应用中,printf()中能填入中文、英文、数字且不限制长度。
①
#include
int main()
{
printf("我是");
printf("C语言");
printf("初学者。");
return 0;
}
运行结果:
我是C语言初学者。
②
#include
int main()
{
printf("我是\t"); # \t表示输出一个tab符
printf("C语言\t");
printf("初学者。\n");
return 0;
}
运行结果:
我是 C语言 初学者。
③
#include
int main()
{
printf("我是\n"); # \n表示输出一个回车
printf("C语言\n");
printf("初学者。\n");
return 0;
}
运行结果:
我是
C语言
初学者。
注意:
①括弧里面一定要有且只能是双引号,我们输出的类容是双引号里面的内容。
②语句后面一定要有分号。在 C 程序中,分号是语句结束符。它表明一个逻辑实体的结束。所以每个语句必须以分号结束。
③如果一旦使用了printf语句,在最后那个语句后面最好都加上一个\n,如果不加的话,你在运行下一个程序时,他可能顺着上一个程序结果后面接着输出,看起来也非常不舒服。
整数用int。带小数的用float或者double,其中double小数点后面允许的小数比float多,当然占用空间也比float多。
平常练习时,其实float的位数也够我们用,所以平时爱用哪个用哪个。如果想用某个变量等于某个字母,使用char。
同时可以赋多个值,中间用逗号隔开。
int a = 100, b, c = 3; #末尾一定要有分号
相当于:
int a = 100;
int b;
int c = 3;
或
int a, b, c;
a = 100;
c = 5;
其中字母也能做加减法,大写字母加32等于他对于的小写字母。注意的是,定义字母的时候一定是单引号(’’)。即:
#include
int main()
{
char x = 'A';
x = x + 32;
printf("x = %c",a);
return 0;
}
输出结果:
x = a
其中a = a + 32也可以写成a += 32:
#include
int main()
{
char x = 'A';
x += 32;
printf("x = %c",x);
return 0;
}
同理加减乘除都可以写作这种形式:
#include
int main()
{
char x = 'A', y = 'b';
int z1 = 10, z2 = 10;
x += 32;
y -= 32;
z1 *= 2;
z2 /= 2;
printf("x = %c, y = %c, z1 = %d, z2 = %d",x,y,z1,z2);
return 0;
}
输出结果:
x = a, y = B, z1 = 20, z2 = 5
int类型输出用%d代替。
#include
int main()
{
int a = 5;
printf("a = %d",a);
return 0;
}
小数类型(float、double)输出用%f代替。
#include
int main()
{
double a = 3.14;
printf("a = %f",a);
return 0;
}
char类型输出用%c代替。
#include
int main()
{
char a = 'A' + 32;
printf("a = %c",a);
return 0;
}
当定义的数在运算后非常大时,就可以用科学计数法,输出的形式用%e。
#include
int main()
{
double a = 152.6752445;
printf("a = %e",a);
return 0;
}
输出结果:
a = 1.526752e+002
特殊的输出方法比如输出的形式为printf("%5d",a),这个5是指输出的空间为5,比如输出900,900占三个格,则前面补两个空格,如果输出位数大于预定位数,则按实际位数输出。
#include
int main()
{
int a = 900, b = 50000;
printf("%5d,%5d",a,b);
return 0;
}
输出结果:
900,50000
如输出的形式为printf("%-5d。",a),符号就是在后面补空格,比如输出500,500占三个格,则后面补两个空格。
#include
int main()
{
int a = 900;
printf("%-5d。",a);
return 0;
}
输出结果:
900 。
如果输出的形式为printf("%.2f",a),就是保留两位小数的意思。
#include
int main()
{
double a = 3.1415926;
printf("%.2f",a);
return 0;
}
输出结果:
3.14
当然我们可以将上面组合使用,如果输出的形式为printf("%8.2f。\n",a),就是占8个位置,并且保留两位小数的意思。
#include
int main()
{
double a = 23.1415926;
printf("%8.2f。\n",a);
printf("%-8.2f。\n",a);
return 0;
}
输出结果:
23.14。
23.14 。
scanf 的功能用一句话来概括就是“通过键盘给程序中的变量赋值”。同时,使用scanf输入时,变量值前面要带&符号,而printf输出时不用。
int型
#include
int main()
{
int a, b;
printf("请输入您的a与b的值。(格式:a,b)\n");
scanf("%d,%d",&a,&b);
printf("您的a = %d, b = %d\n",a,b);
return 0;
}
输出结果:
请输入您的a与b的值。(格式:a,b)
10,20
您的a = 10, b = 20
float型
#include
int main()
{
float a, b;
printf("请输入您的a与b的值。(格式:a,b)\n");
scanf("%f,%f",&a,&b);
printf("您的a = %f, b = %f\n",a,b);
return 0;
}
输出结果:
请输入您的a与b的值。(格式:a,b)
3.14,10.596
您的a = 3.140000, b = 10.596000
double型
#include
int main()
{
double a, b;
printf("请输入您的a与b的值。(格式:a,b)\n");
scanf("%lf,%lf",&a,&b);
printf("您的a = %f, b = %f\n",a,b);
return 0;
}
输出结果:
请输入您的a与b的值。(格式:a,b)
16.468,1156.23
您的a = 16.468000, b = 1156.230000
值得一提的是,double类型输出和float类型一样用%f,而输入时两者却不相同,float依旧用%f,而double却是用%lf。
char型
#include
int main()
{
char a, b;
printf("请输入您的a与b的值。(格式:a,b)\n");
scanf("%c,%c",&a,&b);
printf("您的a = %c, b = %c\n",a,b);
return 0;
}
输出结果:
请输入您的a与b的值。(格式:a,b)
x,z
您的a = x, b = z
注意:getchar()语句和putchar()语句
这两个语句都是与字符挂钩的,getchar()是从键盘上获取字符,putchar()是输出字符。也就是说getchar()能代替scanf(“%c”,&a),putchar()能代替printf(“%c”,a)。
#include
int main()
{
char a;
printf("请输入:");
a = getchar();
printf("您的值为:");
putchar(a);
return 0;
}
输出结果:
请输入:b
您的值为:b
一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。
C 语言中 if 语句的语法:
#include
int main()
{
if(expr1)
{
//codes(如果布尔表达式为真将执行的语句)
}
else if(expr2)
{
//code
}
else if(expr3)
……
else{
//code
}
return 0;
}
执行时,会依照书写顺序,依次判断各个expr,如果有一个为真,则执行后续的{}内语句,并不再执行后续判断,而是直接从out of check开始执行。
else if的数量不限,可以不存在,也可以有任意多组。
else同样可以不存在。
每个else 与最其之前最近的没有匹配else的if相结合。
判断执行的语句{}部分,大括号对可以省略,省略后,if仅对其下一语句生效。
一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。
#include
int main()
{
switch(整形表达式)
{
case 常量表达式1: 语句1;
case 常量表达式2: 语句2;
……
case 常量表达式n: 语句n;
default: 语句n+1;
}
return 0;
}
注意:表达式的值与case后的值相同则进入,case顺序不影响结果
与if语句的不同:
If语句中若判断为真则只执行这个判断后的语句,执行完就跳出if语句,而switch语句不会在执行判断为真后的语句之后跳出循环,而是继续执行后面所有case语句。所以一般我们经常会在每一case语句之后增加break语句,使每一次执行之后均可跳出switch语句,从而避免输出不应有的结果。
一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
百度百科:三目运算符,又称条件运算符,是计算机语言(c,c++,java等)的重要组成部分。它是唯一有3个操作数的运算符,所以有时又称为三元运算符。一般来说,三目运算符的结合性是右结合的。
其中,expr1、expr2和 expr3是表达式。请注意,冒号的使用和位置。
对于条件表达式b ? x : y,先计算条件b,然后进行判断。如果b的值为true,计算x的值,运算结果为x的值;否则,计算y的值,运算结果为y的值。一个条件表达式绝不会既计算x,又计算y。例如:
#include
int main()
{
int num;
printf("请输入一个数字:");
scanf("%d",&num);
(num%2==0?printf("偶数"):printf("奇数"));
return 0;
}
输出结果:
请输入一个数字:21
奇数
只要给定的条件为真,C语言中的while循环语句会重复执行一个目标语句。
C语言中while循环的语法如下所示。
#include
int main()
{
while(expr)
{
语句;
}
return 0;
}
在这里,语句可以是一个单独的语句,也可以是几个语句组成的代码块。
语句可以是任意的表达式,当为任意非零值时都为true。当条件为true时执行循环。当条件为false时,退出循环,程序流将继续执行紧接着循环的下一条语句。
不像for和while循环,它们是在循环头部测试循环条件。在C语言中,do…while循环是在循环的尾部检查它的条件。所以do…while循环会确保至少执行一次循环。
C语言中do…while循环的语法如下所示。
#include
int main()
{
do{
语句;
}
return 0;
}
在这里,条件表达式出现在循环的尾部,所以循环中的语句会在条件被测试之前至少执行一次。如果条件为真,控制流会跳转回上面的do,然后重新执行循环中的语句。这个过程会不断重复,直到给定条件变为假为止。
for循环允许您编写一个执行指定次数的循环控制结构。
for 循环语句的一般形式为:
#include
int main()
{
for(表达式1;表达式2;表达式3)
{
语句;
}
return 0;
}
注意:
①表达式1、表达式2和表达式3之间是用分号;隔开的,千万不要写成逗号。
②for (表达式1; 表达式2; 表达式3)的后面千万不要加分号,很多初学(比如我)都会犯这种错误——会情不自禁地在后面加分号。
关于自增和自减
到for循环这,大家可能就对自增自减有了很大的困惑。我在之前的Java的学习中第一次接触到自增自减也是抓耳挠腮的。我来分享下我对他们的理解。
自增运算符++使操作数的值加1,其操作数为变量。++i表示,i自增1后再参与其它运算;而i++则是i参与运算后,i的值再自增1。
简单地说++i和i++在单独使用时,都表示i=i+1。而a=++i就相当于i=i+1,a=i;a=i++就相当于a=i,i=i+1。同理,自减运算符–与之类似,不予列出。
break语句,它不仅可以跳出“循环体”,还可以跳出switch。但事实上break也只能用于这两种情况。break语句几乎不能用于循环语句和switch语句之外的任何其他语句中。
不管是for循环,还是while循环,或者是do…while循环,都可以用break跳出来,但是break只能跳出一层循环。当有多层循环嵌套的时候,break只能跳出“包裹”它的最里面的那一层循环,无法一次跳出所有循环。
continue语句和break语句的区别是,continue语句只结束本次循环,而不是终止整个循环。break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
一维数组
C语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组包含给定类型的一些对象,并将这些对象依次存储在连续的内存空间中。每个独立的对象被称为数组的元素。
在C中要声明一个数组,需要制定元素的类型和元素的数量,如下所示:
#include
int main()
{
type arrayName [arraySize];
return 0;
}
arraySize必须是一个大于零的整数常量,type 可以是任意有效的C数据类型,如int,char,double等,也可以是个变量。
二维数组
二维数组定义的一般形式是:
#include
int main()
{
type arrayName [arraySize1][arraySize2];
return 0;
}
我们可以把二维数组看成一个矩阵,有行有列,arraySize1表示行数,arraySize2表示列数,想要得到数组中某个元素,则需指明该元素的行和列。并且二维数组的位置永远是0开始。
在c 语言中,将字符串作为字符数组来处理。
字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素:
#include
int main()
{
char str1[12]={'h','e','l','l','o'};
printf("str1的类容:%s\n",str1);
return 0;
}
输出结果:
str1的类容:hello
可以用字符串常量来初始化字符数组:char str2[ ]={“hello”};与上面等价。
#include
int main()
{
char str2[ ]={"hello"};
printf("str2的类容:%s\n",str2);
return 0;
}
输出结果:
str2的类容:hello
注意:上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值。
逐个字符输入输出,用个个格式符%c输入或输出一个字符
#include
int main()
{
char str1[12]={'h','e','l','l','o'};
printf("str[0]的类容:%c\n",str1[0]);
return 0;
}
输出结果:
str[0]的类容:h
将整个字符串一次输入或输出。用%s格式符,意思是对字符串的输入输出。上面列子有使用。
函数是一组一起执行一个任务的语句。每个C程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。我们可以把代码划分到不同的函数中。如何划分代码到不同的函数中是我们自己来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。函数还有很多叫法,比如方法、子例程或程序等等。
从形式上看,函数可分为两类:有参函数和无参函数
有参函数,是指在主调函数调用被调函数时,主调函数通过参数向被调函数传递数据。在一般情况下,有参函数在执行被调函数时会得到一个值并返回给主调函数使用。
定义有参函数的一般形式为:
#include
int main()
{
函数类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, …, 参数类型n 参数名n)
{
声明部分;
语句部分;
}
return 0;
}
参数可以是一个,也可以是多个。
所谓无参函数,是指在主调函数调用被调函数时,主调函数不向被调函数传递数据。
无参函数一般用来执行特定的功能,可以有返回值,也可以没有返回值,但一般以没有返回值居多。
无参函数一般用来独立地完成某个功能,它不接收用户传递的数据。
定义无参函数的一般形式为:
#include
int main()
{
函数类型 函数名()
{
声明部分
语句部分
}
return 0;
}