现在的位置: 首页 > 综合 > 正文

C语言学习笔记

2013年06月21日 ⁄ 综合 ⁄ 共 6688字 ⁄ 字号 评论关闭

C语言学习笔记

第一章 C
语言概述

1.
运行c
程序的步骤

   上机输入与编写源程序->
对源程序进行编译
(
目标程序
object program)->
与库函数连接
->
执行目标程序。整个步骤的说明:

编辑程序保存得到一个源程文件program.c
,然后在进行编译时再将源程序文件
program.c
输入,经过编译得到的目标程序文件
program.obj,
再将其目标文件
program.obj
输入内存与系统提供的库函数等连接,得到可执行的目标程序
program.exe
,最后把
program.exe
调入内存并使之运行。

为了编译,连接和运行c
程序,必须要有相应的
c
编译系统,目前使用的大多数
c
编译系统都是集成环境
(IDE)
的,把程序的编辑,编译,连接和运行等操作全部集中在一个界面上进行,功能丰富,使用方便,直观易用。编译系统
(Turbo C2.0 Turbo C++3.0 Visual C++).
由于
C++
是从
C
语言发展起来的,所以
C
程序可以在
C++
集成环境中进行编译,调试和运行。

第三章 数据类型,运算符和表达式

1数据类型
,
运算符和表达式

1.1在一般的编译系统中
Int 
类型的数据为其分配
2
个字节
(16

)
,但是
Visual C++6.0
为整型分配
4
个字节
(32

)

Short--2Bit Int--4Bit


1.2
Turbo 
系列的编译系统中,一个
int
型的变量的最大值允许为
32767
,如果加
1
,将会出

现益
处现象。说明:
在计算机内int
数据的存储格式都是以它的补码形式存放的,
32767
最高位是
0(
正数
)
,其余
15
位都是
1
,加上
1
后变成第一位是
1
,其余
15
位是
0
,而它是
-32768
的补码形式,将其通过反码转换成源码就是
-32768


1.3 一个整型常量后面加上一个字母
u
或者
U
,认为是
unsigned int
型,如
12345u
在内存中是按
unsigned int
规定的方式来存放的
(
存储单元中最高位不作符号位,而用来存储数据
)
。如果写成
-12345u
,则先将
-12345
转换成其补码,然后按无符号数存储。

1.4 一个浮点型数据一般在内存中占
4Bit(32bit)
,与整形数据的存储方式不同,浮点型数据时按照指数形式存储的。系统吧一个浮点数据分成小数部分和指数部分。

1.5 字符型变量用来存放字符常量,只能放一个字符,将一个字符常量放到一个字符变量中,实际上并不是把该字符本身存放到内存中,而是将该字符相应的
ASCII 
代码存放到存储单元中。说明:字符
'a'

ASCII
码是十进制
97
,但是在内存中是
97
的二进制存放的。所以
int

char
之间可以通用,进行算术运算。

1.6 'a'
"a"
的区别。
C
规定:在每一个字符串常量的结尾加一个
"
字符串结束标记
"('/0')
,以便系统判断字符串是否结束。
'/0'
是一个
ASCII
码为
0
的字符,是
"
空操作符
"
,即它不引起任何控制动作,也不是一个可显字符。
"a"
包含
a

'/0'
,包含两个字节,因此不能用
char
字符变量来存储,可用
char
型数据来存储。

1.7 变量赋初值 
int a=3,b=3,c=3; 
不能写成 
int a = b = c = 3; 
说明:初始化不是在编译阶段完成的
(
静态存储变量和外部存储变量的初始化是在编译阶段完成的
)
,而是在程序运行时执行本函数时赋初值的,相当于 
int a,b,c; c=3;.

1.8 各类数值型数据间的混合运算  字符数据必定先转换成整数,
short 
转换为
int

float
在运算时一律先转换为双精度
(double)
,然后再相加。不同类型转换:
int

double
间进行运算,先将
int
型转换成
double
,再相加。
Int(char,short)->unsigned->long->double(float)


1.9 强制类型转换运算符  可以利用强制类型转换运算符将一个表达式转换成所需类型。
(double)a  (int)(x+y)   (float)(5%3)

(int)x+y:

x
转换成
int
整型再与
y
相加。说明:在强制类型转换时,得到一个所需类型的中间变量,原来变量的类型未发生变化。有两种类型转换:一种是在运算时不必用户指定,系统自动进行的类型转换,如
3+5.4.
第二种是强制类型转换,当自动类型转换不能实现目的时,可以用强制类型转换,如
"%"
运算符要求其两侧均为整型,若
x

float
,则
"x%3"
不合法,必须用
"(int)x%3".
因为强制类型转换运算优先于
'%'
,因此先进行
(int)x
的运算,得到一个整型的中间变量,然后再对
3
求模。

1.10  自曾运算符
(++)
和自减运算符
(--)
只能用于变量,而不能用于常量和表达式。如
5++

(a+b)++
都是不合法的,因为
5
是常量,常量的值是不能改变的;若
a+b
的值为
5
,那么自增后得到的
6
存放在什么地方,无变量可存放。
-i++ == -(i++) i+++j == (i++)+j
。多数系统中,在调用函数时,是参数的求值顺序
:
自右向左。例子:
printf("%d,%d",i.i++);
先求
i++
,再求
i
。所以避免让别人难以看明白,可以这样写 
j=i++;printf("%d %d",i,j);

1.11  逗号运算符  其求解过程:先求表达式一,再求表达式二,整个表达式的值是表达式二的值。例子
:a=(3*5,a*4),a+5;
计算过程:先计算出
a
的值是
3*5=15
,再进行
a*4=60(

a
值没有变化,仍为
15)
,再
a+5=20
,所以整个表达式的值为
20

(x=a=3,6*3)
,其包括一个赋值表达式和一个算术表达式,
x
的值是
3
,整个表达式的值是
18


第四章 最简单的C
程序设计
--
顺序程序设计

赋值语句

  C语言中的赋值号
"="
是一个运算符,在其他大多数语言中赋值号不是运算符

数据输入输出的概念及在
C
语言中的实现

  C语言本身不提供输入输出语句,输入输出操作是
C
函数库中的函数来实现的。在
C
标准函数库中提供了一些输入输出函数,例如
printf

scanf
,不要误认为他们是
C
语言中提供的
"
输入输出语句
"

printf

scanf
不是
C
语言的关键字,而是函数的名字。
C
提供的函数是以库的形式存放在系统中,他们不是
C
语言文本中的组成部分。不把输入输出作为
C
语句的目的是使
C
语言编译系统简单,因为将语句翻译成二进制的指令是在编译阶段完成的,没有输入输出语句就可以避免在编译阶段与硬件相关的问题,可以使编译系统简化,而且通用性强,可移植性好,在各种型号的计算机厂商
(
或软件公司
)
根据用户的需要编写的,并且已编译成目标文件
(.obj).
他们在连接阶段与由源程序经编译而得到的目标文件相连接,生成一个可执行的目标文件
(.exe)
。如果在源程序中有
printf
函数,在编译时并不是把他翻译成目标指令,在连接阶段与系统函数库相连接后,在执行阶段中调用函数库中的
printf
函数。加入函数库
#include <stdio.h>

第五章 
 选择结构程序设计

1.
关系表达式的值是一个逻辑值,即"

""

"

C
语言没有逻辑型数据
(C++
有逻辑型变量和逻辑性常量,以
True

False)
。在
C
的逻辑运算中,以
"1""0"
分别表示真,假。字符型,实型或者指针型,系统以
0
和非
0
来判断,他们
ASCII
不为
0
,则为非
0
,即为真。

2.
条件运算符 例子:x>y?1:1.5;
如果
x<=y,
则值为
1.5,

x>y
,值应为
1
,由于
1.5
是实型,比整型的优先级高,将
1
转换成实型值
1.0
。则值应为
1.0


第七章 
数组

1.
C语言规定只能逐个引用数组元素而不能一次引用整个数组。数组下标可以是整数常量和整型表达式。
A[2*3];

2.
一维数组的初始化。Int a[10]={1,2,3,4,5,6,7,7,8,9};
,可以只给一部分元素赋值,如果全部元素都一样可以
a[10]={0};
在确定元素个数时可以不指定其长度。

3.
二维数组的初始化。Int a[2][3]={{1,2,3},{3,4,5}};
可以将所有数据写在一个花括号内,安数组排列的顺序对各元素赋值。

4.
字符数组与字符串常量。在C
语言中,是将字符串作为字符数组来处理的。但在数组中
'/0'
只能认为加上,如果要有效的利用字符数组,最好与字符串常量在内存中的存放保持一致,即在数组最后加上一个
'/0'
来判断字符串的结束。例如:
char c[]="cccc program";
若想用一个新的字符串代替原有的字符串
"cccc program",
从键盘响字符数组中键入
chen
,如果不加
'/0'
,则输出的是 
"chen program".

第八章 
函数

1.
函数类型为void
,意为函数无类型,即无函数值,执行这个函数后不会把任何值带回
main
函数。

2.
C
语言中,实参向形参的数据传递的是
"
值传递
"
,单项传递,只由实参传给形参,而不能有形参传回来给实参。在内存中,实参单元与形参但与是不同的存储单元。在调用函数时,才给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。因此,在执行一个被调函数时,形参的值如果发生改变,并不会改变主调函数的实参的值。

3.
C
语言中,若不加函数类型说明的函数,系统将自动按整型处理。

4.
许多系统,安自右到左的顺序求值的。如:p=f(i,++i);
那么第二个参数将先执行,
i
若为
2
,参加运算
(++i)
后为
3
,则第一个参数为
3


5.
函数的声明"declaration".
作用:是把函数名,函数参数个数,参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。如果已在文件的开头
(
在所有函数以前
)
,已对本文件中所调用的函数进行了声明,则在各函数中不必对其所有调用的函数再做声明。

6.
数组名也可以用作实参和形参,传递的是数组的首地址。类似与指针,因此形参数组中的各元素发生变化会使实参数组元素同时发生变化;数组元素做函数实参与变量作实参一样,是单向传递,即"
值传递
"


7.
二维数组做实参和形参,并需指定列数(
一行中包含几个元素
)
。因为:在内存中,数组是按照行存放的,只要确定了列数,实参和形参的元素才能对号入座。如
:a[][4]; f(b[][4]);

8.
全局变量在不是很必要时不要使用,原因:
㈠全局变量在程序的全部执行中都占用存储单元,而不是仅在需要时才开辟单元;㈡它使函数的通用性降低,因为函数在执行时需要依赖于其所在的外部变量;㈢使用过多会降低程序的清晰性;㈣如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被
"
屏蔽
"
,即它不起作用。

9.
变量的存储类别  从变量值存在的时间来分,可以分为静态存储方式(
在程序运行期间由系统分配固定的存储空间
)
和动态存储方式
(
根据需要进行动态的分配存储空间
)
。内存中提供给用户的存储空间分为三部分
:1.
程序区
;2.
静态存储区
3.
动态存储区。数据分别存放在静态和动态存储区中。全局变量全部存放在静态存储区中,在程序开始执行时给全局变量分配存储区,程序执行完毕就释放。在程序执行过程中他们占固定的存储单元,而不是动态进行分配和释放。动态存储区存放以下数据
:1.
函数形式参数,在调用函数时给参数分配存储空间
2.
自动变量
(
没加
static
声明的局部变量
)3.
函数调用时的现场保护和返回地址等。以上这些数据,在函数调用开始时分配动态存储空间,函数结束时释放空间。在程序执行过程中,这些分配和释放都是动态的,如果在一个程序中两次调用统一函数,分配给此函数中局部变量的存储空间地址可能是不相同的。如果一个程序包含若干个函数,每个函数中的局部变量的生存周期并不等于整个程序的执行周期,只是程序执行周期的一部分。

10.
Auto变量 函数中的局部变量,如果不专门声明为
static
存储类型,都是动态地分配存储空间。在函数调用时会自动分配空间,函数调用结束时会自动释放空间,这类局部变量称为自动变量 
auto int a = 3 == int a =3;

11.
Static声明局部变量 函数中的局部变量的值在函数调用结束后不消失而保留原值,其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。说明
:1
静态局部变量属于静态存储类型,在程序整个运行期间都不释放。
2
对静态局部变量时在编译是赋初始值,即只赋初值一次,在程序运行时他已有初值。

在定义局部变量不赋值的话,对静态局部变量而言,编译时自动赋值
0(
对数值
)
或空字符
(
对字符
)
。而对自动变量来说,不赋值则它的值是一个不确定的值,这是由于每一次函数调用结束后存储单元也释放,下次调用时有重新另分配存储单元,其值是不确定的。
4
在函数结束时仍然存在,但其他函数无法引用它。

12.
Static 声明外部变量 该外部变量只能在本文件中被使用,其他文件不能访问。
File.c static int a; file2.c extern int a; 

file2.c
中不能访问
file.c
中的
a
变量。

static
来声明一个变量作用有二:①对局部,则使该变量在整个程序执行期间不释放,为其分配的空间始终存在②对全局,作用域只限于本文件模块
(
即被声明的文件中
)


13.
register变量 将变量存放在
cpu
的寄存器中,加快数据访问。通常用于较高的循环。但不是很常用。  变量的执行过程
:
程序中用到的变量时,由控制器发出指令将内存中该变量的值送到运算器中,经过运算器运算,如果需要存储,将值从运算器到内存中。

14.
Extern声明外部变量  如果外部变量不在文件的开头定义,其有效作用域只限于定义处到文件借书处。
Extern int a 
在文件的任何地方定义,
a
的范围都是整个文件。

15.
Extern在多个文件中定义  
file1.c auto int a;file2.c extern int a;
能访问
file1.c
中的
a


16.
内部函数 static int fun1();
只能在本文件中访问
extern int fun2();
访问的是另外文件中的函数。

第九章 
预处理命令

ANSI C标准规定可以在
C
源程序中加入一些
"
预处理命令
(preprocessor directives)",
以改进程序设计环境,提高编程效率。这些预处理命令是有
ANSI C
统一规定,但不是
C
语言的组成部分,不能直接对他们进行编译
(
编译程序不能直接识别它们
)
。必须对程序进行通常的编译
(
包含词法和语法分析,代码生成,优化等
)
之前,先对程序中这些命令进行预处理。预处理之后的程序不再包括预处理命令了,最后再有编译程序对预处理后的源程序进行通常的编译处理,得到可执行的目标代码。

1.
宏定义 #define PI 3.1415926  #define S(a,b) a*b

2.
文件包含 #include <stdio.h> 
系统自带文件  
#include "myfile.h" 
用户自定义文件

3.
条件编译 

#ifdef(ifndef) 标示符 
(if  
表达式
)  ifdef 
如果定义 程序
1

ifndef 
如果为定义 程序段
1


程序段1

#else

程序段2

#endif

第十章 
 指针

1.
通过指针引用数组元素 如果p
的初始值为
&a[0],
则⑴
p+i

a+i
就是
a[i]
的地址,他们指向
a
数组的第
i
个元素。⑵
*(p+i)

*(a+i)

p+i

a+i
所指向的数组元素⑶指向数组的指针变量也可以带下标,如
p[i]==*(p+i).

2.
多维数组与指针  从二维数组的角度来看,a
代表二维数组首元素的地址,现在的首元素不是一个简单的整型元素,而是由
n
个元素所组成的一维数组,因此
a
代表的是首行的首地址。
a+1
代表第一行的首地址。
a[0]==*(a+0),a[1]==*(a+1),a[0]+1==*(a+0)+1==&a[0][1];

3.
C语言对字符串常量是按字符数组处理的,在内存中开辟一个字符数组来存放该字符串常量。对字符串指针变量
string
初始化,实际上时把字符串第一个元素的地址赋给
string

Printf("%s/n",string);%s
输出字符串时所用的格式符,在输出项中给出字符指针变量名
string
,则系统先输出它所指向的一个字符数据,然后自动使
string

1
,使之指向下一个字符,然后再输出它所指向的一个字符,直到遇到结束标记
'/0'
为止。注意:在内存中,字符串的最后被自动加了一个
'/0'


抱歉!评论已关闭.