前言:
1.初学习了c语言,感觉还是很不错的,哈哈~~。下面让我来分享下我目前对c的认识
题外:后面有关于c语言风格培养的《高质量的c-c++编程》PDF版链接,有需要自拿。哈哈~~。
一.初识c语言
1.1计算机语言的发展过程:由需求促进发展,由不成熟逐渐成为流行。
早期的科学家通过数字1和0的组合控制硬件计算机的运行。后来在需求下,人们创建了助记符(汇编语言).但还是不能满足需求,于是B语言出现,再后来高级语言C,c++,java等相继出现。但不同地方语言规范不同,为消除这种交流障碍,促进语言的融洽,1989年,ANSI(美国国家标准协会) 制定了一套c语言规定(c89 ),1990年,国际标准化组织(IOS) 也制定了一套规定(c90).1999年,ANSI/IOS(C9X委员会)联合委员会共同制定了c99;2011年,C9x发布了(C11 )标准。至此C语言成为世界流行语言。目前使用较多的是c89/c90(2个几乎等同),
1.2什么是c语言?
c语言是一种面向过程的计算机编程语言 ,广泛用于底层 C语言的设计目标 是提供一种 能简易编译,处理低级存储器 ,产生少量机器码 以及不需要任何运行环境支持便能运行的编程语言。
选择C语言的理由:流行性,高效性,可移植性高,强大而灵活,面向程序员 。
1.流行性:c是一门流行语言。其融合了计算机科学理论和实践的控制特性。便于用户完成自顶向下的规划,结构化编程和模块化设计。使得c语言编写的程序更易懂,更可靠。
2.高效性:c是高效的语言。c语言具有通常汇编语言才有的微调控控能力,可以根据具体情况一获得最大运行速度,最有效的使用内存 。
3.可移植性高:c是可移植的语言。我们知道不同操作系统其运行方式不同。而我们想在不同系统运行c程序,需要我们在少量更改程序的条件下,仍能运行c程序。这必然要求我们的语言可移植性高。而在这些语言中,c语言崭露头角,其可移植性非常高
4.强大而灵活:许多操作系统,如UNIX系统大部分也是通过c语言编写的。另外很多程序编译器,解释器也是用c语言编写的。
5.面向程序员:c语言的强大,可以清晰的让程序员简洁的表达自己的想法与意图。
简单的c程序
# include <stdio.h>
int main ( )
{
printf ( "helloworld!" ) ;
return 0 ;
}
据说在业界能这句话能给你的编程之旅带来好运!你好世界!
三.c语言的语法规则
3.1 c中的数据类型:整形,浮点型,字符型及其所占空间大小
整型
名字
int
(普通整形),
short (int)可以省略(int)
短整形
long
长整形
long long
更长的整形
unsigned int
无符号(—)整形(只能为正)
signed int
有符号整型(一切整数)
浮点型:
名字
float
单精度浮点数型
double
双精度浮点型
3.1.2 每种数据类型的在内存中的大小
补充:
1.sizeof(类型)
1.它是运算操作符 ,不是函数
2.它用于测定数据在内存中的字节(byte)大小,字符串结束标志‘\0’也要被计算内存。
2.strlen(字符数组名)
1.它是函数 ,不是操作符。
2.它用于测定字符数组长度。在测定长度时以’\0’为字符串结束标志。
3.字节(byte)
计算机的单位:
内存单位
名字
补充
bit
比特
计算机最小内存单元
byte
字节
1byte=8bit
kb
1kb=1024byte
mb
1kb=1024kb
gb
1kb=1024mb
tb
1kb=1024gb
pb
1kb=1024tb
我们知道计算机能识别的机器语言(二进制语言)(一定顺序的1/0),而对于每个二进制1/0在内存中都要占有一定的空间,我们规定每个 这样的1/0所占的空间为1bit(计算机中的最小内存空间)。而计算机中的数据是按字节,分配空间的,即认为1byte为运行时的内存单元。
01000100 占用1个字节空间(8个bite位)
而对于数据类型我们规定:
类型
内存大小
整型(int)
4个字节(32bite位)
短整形(short)
2个字节(16个bite位)
long long型
8个字节。
类型
内存大小
字符型
一个字节(8个bite位)。
类型
内存大小
单精度型(float)
4个字节(32个bite位)
双精度型(double)
8个字节(64个bite位)。
==另外c语言规定:sizeof(long) >sizeof(int)=4;具体long型所占字节大小,依据不同编译器结果不同。
3.2变量,常量
3.2.1.变量:可以随时改变的量(数据).如:年龄,身高等;
3.2.2.常量:不能改变的量(数据)。如:圆周率,血型等。
3. 2.3定义变量的方式:
数据类型+自定义数据名称+初始化+语句结束标志“;”(分号)
初始化依据条件可以不进行初始化。
如 年龄是整形 数据
身高是浮点型 数据
字母是字符型 数据
int age= 19 ;
float length= 170f ;
char a= 'w' ;
3.2.4变量的使用:
# include <stdio.h>
int main ( )
{
int age= 19 ;
float length= 170f ;
char name[ ] = "***" ;
printf ( "年龄=%d\n" , age) ;
printf ( "长度=%f\n" , length) ;
printf ( "名字=%s" , name) ;
return 0 ;
}
3.2.5变量的分类
局部变量:
定义 在一对{}内的变量都是局部变量,无论是main函数还是普通函数。
全局变量:
注意
当全局变量与局部变量冲突时,遵从“局部变量优先原则 ”
3.2.6变量的作用域与生命周期————有效使用变量
局部变量:
1.作用域:在所创建位置的一对{}内的任何地方 都可以使用:
2.生命周期:
局部变量自创建的一对{}始 ,到出这对{}为止 ,这段时间为其生命周期; **
right:
a创建于最外面的{} ,所以main函数内 的任何地方都可以使用。
a创建于里面的{} ,所以里面{}内的任何地方 都可以使用。
error
思考
# include <stdio.h>
int main ( )
{
{
int a= 1 ;
printf ( "%d\n" , a) ;
}
printf ( "%d\n" , a) ;
return 0 ;
}
#include<stdio.h>
int main()
{
int a = 1;
{
int a=1;
printf("%d\n", a);
}
printf("%d\n", a);
return 0;
}
全局变量:
1.作用域:自创建到程序结束的任何地方都可以使用。
2.生命周期:自创建到程序结束为其生命周期。
3.2.7常量:
1.字面常量:血型,名字等
2.const修饰常变量(一旦const就不可更改 ):
#include<stdio.h>
int main()
{
const int a=19;
a=22;//变量一旦const就不可更改,重新赋值。
printf("%d",a);
return 0;
}
3.#define定义的标识符常量
注意
1.define定义的宏常量不占用内存,它只会傻瓜式的语言替换。
分析 :
结果并不是20 ,而是12 的原因是:t=x+2*2;
4.枚举常量
当一个变量的所有可能 都可知 的情况下,我们常定义枚举常量;如性别,数据类型等
c语言规定 :枚举常量中的第一个常量在数值上是0,其它依次加1。如果人为的初始化第一个常量,其它常量任然依次加1. **
3.3字符与字符串+转义字符+注释;
3.3.1.字符与字符串:
字符:像‘w’这种由一对‘ ’所引用的字符。
字符串:”name“像这种用一对” “所引用的连续字符,称为字符串。
因为c语言中没有字符串型数据,因此我们用字符数组定义字符串;
3.3.2.转义字符:
补充:
1.在计算机中,为了方便字符型与实型数据间的运算,我们人为的规定每个字符 对应的一个十进制数。为此我们制定了ASII表
注意
常用转义字符:‘\n’,’\t’,’\ddd’,’\xdd’;
注意
3.3.3.注释
1.在c程序中我们想解释自己的程序时,我们常使用“//”;
2.在c程序中我们想保留部分程序,不让其起作用时,
注意
3.4 c语言的3种结构:顺序,选择,循环。
3.4.1顺序:一步一步执行代码。
3.4.2选择结构(分支语句):
注意
3.4.2.1 if语句
1.if语句的2种 形式
第一种
if(表达式){语句体}
else 语句体
第二种
if(表达式){语句体}
else if(表达式) {语句体}
…
else 语句体
注意
1.我们规定else 与最近的 if 匹配.
2.注意if语句体中的关键字 break,continue;
看题
# include <stdio.h>
int main ( )
{
int a = 0 ;
int b = 2 ;
if ( a == 1 )
if ( b == 2 )
printf ( "hehe\n" ) ;
else
printf ( "haha\n" ) ;
return 0 ;
}
思考这题的输出结果
答案:
什么都不输出思考注意中的第一点
2 .switch语句:
1.switch语句的形式
switch(整形表达式)
{
case 整形常量表达式:语句;
…
}
注意
1.switch中的整形表达式不可以 为浮点型数据 ,但可以为,枚举类型(可以当作是整形常量),字符型数据 (计算机在碰到字符新数据时会将它自动转化为整形 进行运算)(图一 )
2.case 中的必须为整形常量 ,或者是枚举类型(枚举也看以看作是一种特殊常量)
3.switch中的关键字 break 是用于分开语句块 的。且不能使用 关键字continue ;(图二 )
4.当执行的case没有break作为跳出switch时,其会==,默认==继续执行下面的case,直到再次遇到break;(图三)
5.虽然switch中的default 是默认选项 的意思,但使用时多留意其前面是否有 break ;再次体现第三点 的重要性 (图四)
6.default 可以放在switch语句体内的任意位置
看图
图一
图二
图三
图四
问题
# include <stdio.h>
int main ( )
{
int n = 1 ;
int m = 2 ;
switch ( n)
{
case 1 :
m++ ;
case 2 :
n++ ;
case 3 :
switch ( n)
{
case 1 :
n++ ;
case 2 :
m++ ;
n++ ;
break ;
}
case 4 :
m++ ;
break ;
default :
break ;
}
printf ( "m = %d, n = %d\n" , m, n) ;
return 0 ;
}
答案:
分析:(1)-》(2)-》(3)-》(4)-》(5)
(1)先执行外面的swtich,n为1,执行case 1,后m=3.因为其后无break,进行执行case。
(2)执行case 2-》m=3,n=2.
(3)执行case 3->,执行内嵌的switch中的case 2-》m=4,n=3,遇到break,跳出内部switch
(4)执行case 4-》m=5.遇到break,跳出外部switch;
(5)m=5,n=3;
3.4.3循环结构:while,do while,for循环;
1.while语句形式
while(表达式){语句体}
当表达式 为真 是,执行语句体.
2.do …while语句形式
do{语句体}while(表达式);
先 执行语句体 ,后判断表达式
3.for语句形式
for(表达式1,表达式2,表达式3)
表达式1:
表达式1为初始化部分 ,用于初始化循环变量 的。
表达式2:
表达式2为条件判断部分 ,用于判断循环时候终止 。
表达式3:
表达式3为调整部分 ,用于循环条件的调整 。
注意
1.while的执行条件 始终比循环体 多一次 。
2.do while语句注意语句结束 要有分号"";“ ,且其循环体 始终与表达式 执行次数一致。
3.brake只能跳出一层 循环(当内循环结构时,只能跳出内部一层循环结构)
4.continue只能跳出本次 循环。
练一练
打印9*9乘法表
for()形式
int main ( )
{
int i = 0 ;
int j = 0 ;
for ( i = 0 ; i < 10 ; i++ )
for ( j = 1 ; j <= i; j++ )
{
printf ( "%d*%d=%-2d" , i, j, i * j) ;
if ( j == i) printf ( "\n" ) ;
}
return 0 ;
}
分析:通过i控制行,j控制列.
while形式
# define _CRT_SECURE_NO_WARNINGS 1
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <math.h>
int main ( )
{
int i = 1 ;
int j = 0 ;
while ( i < 10 )
{
j = 1 ;
while ( j <= i)
{
printf ( "%d*%d=%-3d" , i, j, i * j) ;
j++ ;
}
printf ( "\n" ) ;
i++ ;
}
return 0 ;
}
分析:外层循环控制行,层控制列
do while形式
int main ( )
{
int i = 1 ;
int j = 0 ;
do
{
j = 1 ;
do
{
printf ( "%d*%d=%-3d" , i, j, i * j) ;
j++ ;
} while ( j <= i) ;
printf ( "\n" ) ;
i++ ;
} while ( i< 10 ) ;
return 0 ;
}
分析:外层循环控制行,层控制列
3.5函数
背景:在一个main函数中,我们可以通过代码的形式完成某些目的,但是这样,main函数就会变得很长。为了尽可能的减少main函数的代码长度,我们创建函数来完成这部分工作。
函数形式:
返回值类型+函数名+(形参1,形参2,…)
# include <stdio.h>
int add ( int x, int y)
{
return x+ y;
}
int main ( )
{
int a = 0 ;
int b = 0 ;
int c = 0 ;
scanf ( "%d%d" , & a, & b) ;
c= add ( a, b) ;
printf ( "%d\n" , c) ;
return 0 ;
}
函数声明形式:
返回值类型+函数名+形式类型+”;“
# include <stdio.h>
int main ( )
{
int add ( int x, int y) ;
int a = 0 ;
int b = 0 ;
int c = 0 ;
scanf ( "%d%d" , & a, & b) ;
c= add ( a, b) ;
printf ( "%d\n" , c) ;
return 0 ;
}
int add ( int x, int y)
{
return x+ y;
}
注意
1.自定义的函数要有返回值.
2.自定义的函数可以放在main函数的前面,或者后面(在后面的时候,要在main函数中提前声明)。
3.实参传递数据到形参时,参数类型要相同,不然会丢失部分数据 。
3.7数组
背景:如果我们想存储一组数,我们一个怎么办呢?这时候即需要c中的数组;
3.7.1数组的定义:
数组元素类型+数组名+【数据数量】;
int arr[ 10 ] = {
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
3.7.2数组下标:
int arr[ 10 ] = {
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
数组长度是10,下标从0~9 ;
3.7.3数组的使用
# include <stdio.h>
int main ( )
{
int i = 0 ;
int arr[ 10 ] = {
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ;
for ( i= 0 ; i< 10 ; i++ )
{
printf ( "%d " , arr[ i] ) ;
}
printf ( "\n" ) ;
return 0 ;
}
注意
1.数组下标小于数组长度,且其最大值为数组长度-1;
2.数组名是数组的首地址;
看题
下面程序有问题吗?
# include <stdio.h>
int main ( )
{
int i = 0 ;
int arr1[ 10 ] = {
0 } ;
char arr2{
10 } = {
0 } ;
char arr3[ 10 ] = {
'0' } ;
printf ( "%d\n" , arr1[ 0 ] ) ;
printf ( "%c\n" , arr2[ 0 ] ) ;
printf ( "%c\n" , arr3[ 0 ] ) ;
return 0 ;
}
分析:
arr1[0]被初始化为0;arr2[0]被初始化为0;arr3[0]被初始化为字符’0’;
0 对于int 型 就是数字0,但对char ,在ASII表中是 空 的意思,即没有任何意义(NULL)。
字符’0’对于char 型是字符串结束标志。
3.8操作符
3.8.1算术操作符:
+,-,*, /,%
注意
除法的2种情况:
/的前后都是 整形数据 时,对结果取整 。
/的前后存在 浮点数 时,结果就是浮点数 。(图一)
# include <stdio.h>
int main ( )
{
int a = 0 ;
int b = 0 ;
int c2 = 0 ;
float c2 = 0 ;
scanf ( "%d%d" , & a, & b) ;
c1= a/ b;
c2= a/ b;
printf ( "%d\n" , c1) ;
printf ( "%f\n" , c2) ;
return 0 ;
}
3.8.2位移操作符:
<<,左位移操作符
>>右位移操作符
它们移动的是补码
补码补充
1.计算机在内存中处理数据,都是按数据的补码 形式进行运算的,最后以原码 的形式表现数据。
2.正数与0的,原码,反码,补码是一样的。
3.负数的原码 是按正数 编时的二进制原码 ;反码 是原码除符号位 ,其它位取反 ;补码 是反码+1 。
题目
#include<stdio.h>
int main()
{
int a=-1;
int b=-1;
printf("%d\n",a<<2);
printf("%d\n",b>>2);
return 0;
}
3.8.3位操作符:&,|,^
注意
运算符
功能
运算规则
&
按位与
对应位均为1时,才位1,否则为0
|
按位或
对应位存在1时就为1
^
按位与或
对应位相同为0,相异为1
<<
左移
补码左移若干位,超出丢弃(不包括1),剩下补0,每左移一位,相当于多乘2;
>>
右移
补码右移若干位,正数左补0,负数左补1,右边溢出丢。
3.8.4赋值操作符:=,+=,-=,*=,/=,&=,|=,<<=,>>=
3.8.5单目操作符:
单目操作符表
单目操作福
功能
!
逻辑反操作
-
负值
+
正值
&
取地址
sizeof
就类型长度(以字节为单位)
~
对一个数的补码按位取反
–
前置:先自减,后应用;后置:先应用,后自键
++
前置:先自增,后应用;后置:先应用,后自增
*
间接访问操作符(解应用操作符)
(类型)
强制类型转换
3.8.6关系操作符:
>,>=,<,<=,==,!=;
3.8.7逻辑操作符(双目运算符 ):
逻辑操作符
功能
&&
且,只有当2边逻辑都为真是才为真
||
或,一边为真即为真
3.8.8条件操作符
3.8.9逗号表达式:
exp1,exp2,exp3…
注意
逗号表达式的运算结果 以最后一项为准。
看图
3.8.10下标引用[],函数调用(),结构体成员->.
3.9关键字
关键字
功能
auto
存储类别说明关键字(局部变量)
break
终止一层循环
case
swtich语句中的case
char
字符数据类型说明关键字
const
将变量定义为长量
continue
结束本次循环,直接执行下次循环
default
switch语句中,当没有满足case的情况,默认执行default语句
do
do {}while();语句中的关键字
double
双精度数据类型说明关键字
else
与最近if匹配的else分支语句
enum
枚举变量的说明关键字
extern
提前告知变量,函数等出现在别的文件中
float
单精度数据类型说明关键字
for
for的说明关键字
goto
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
if
分支语句说明关键字
int
整形数据说明关键字
long
更大整形说明关键字
return
返回某种类型的值,结束函数
short
短整形说明关键字
signed
有符号型说明关键字
sizeof
测定数据占内存空间的大小,单位字节
static
静态成员说明关键字(具体说明看下面)
struct
结构体说明关键字
switch
swtich分支语句关键字
typedef
重新定义数据类型别名 :typedef unint unsigned int
union
联合说明关键字
unsigned
无符号整形说明关键字
void
空类型说明关键字
while
while语句说明关键字
register
volatile
注意
在定义变量,函数名时不能使用关键字
3.9.1static:
1.修饰局部变量:延长 局部变量生命周期 ,不改变 其作用域 (图一)
2.修饰全局变量:改变全局变量的外联性(可被其它文件使用。extern),使全局变量只能被本模块使用。
3.修饰函数:改变函数的外联性(可被其它文件使用。extern),使函数只能被本模块使用。
图一
图二
图三
3.10#define定义宏常量和宏
#define+“空格”+宏常量名+常量
#define+“空格”+宏名+表达式
3.11指针
3.11.1内存:
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
3.11.2内存是怎么被编号的?
我们知道32位计算机有32根物理地址线(通过地址线,寻找相应地址的数据),在通电时,每根电信号被转化为1/0。而这样的32跟地址线,可形参232 种不同的32为位二进制编码。二232 字节换算成G时为4G,在32为系统4G内存足够了。因此以这 232 种二进制(其实是将二进制转化为16进制,编号内存的)为编号刚好,(另外通过增加地址线的方法,可以增加内存)
3.11.3地址的存储
3.11.4指针变量:
3.11.5指针的大小:
前面我们知道,32系统下的32为地址线,通过32位二进制编号内存,所以在内存中我们存储一个地址时需要4个 字节的内存单元,即32位 下指针大小为4字节 。同理64位系统下,指针大小为8字节
3.11.6补充
我们在定义变量时,随机 存储在内存中。当程序结束时,变量内存释放。每次运行,变量都随机存储于内存中。
3.12结构体
前言
对于人这个抽象概念,我们很模糊,但我们具体到某个人时,他的名字,性别等,做为他的具体属性被我们知道。
因此我们定义结构体,用于对具有共同属性的一类事物的 抽象
3.12.1结构体定义:
struct+结构体名
{
属性1;
属性2;
…
};
注意
1.定义结构体不可丢关键字struct
2.结构结尾的分号不能丢
3.12.2结构体数组:
| ------------------------------------------------------------ |
感言:
1.对目前c语言的有些地方学的不深,不敢过多描述。哈哈。
2.在这段学习中,我会了一些小游戏,由其是关机程序,贼有意思!哈哈。后面会补上的。
3.《高质量的c-c++编程》PDF版链接:链接:https://pan.baidu.com/s/1yW6FgsZDqeOtVzePrdZk_Q
提取码:2021