1)某位置上一个真正的语法错误可能导致编译器误认为它发现了其他错误
2)发现的错误位置要比真正的错误要滞后一行
3) 编译器的警告信息表明尽管代码正确,但有可能不是程序员所需要的。
常见开发工具
命令行开发(工具链+源代码+Makefile)
vc ++ 6.0
borland c
嵌入式领域:各种不同单片机以及SOC的开发工具ADS,Keil
4)基本数据类型
C89定义了五种基本数据类型:char ,int ,float(单精度浮点数) ,double(双精度浮点数) ,void
这五种类型构成了其他几种类型的基础。他们的长度和域随处理机类型和编译器的不同而改变(char型的对象在任何情况下都是1B)。C只规定了每种数据类型的最小范围,而不是字节大小。
CPU处理的基本单位.32根数据线。字长是32位那么就是32位处理器,一次处理的数据的位数
整型在32位处理中是4个字节。浮点型的在内存中所占的比例随CPU的不同而不同
C99新增了四种类型:_Bool,_Complex,_Imaginary,long long
字符串不是基本数据类型
5)修饰数据类型
除了void类型外,基本类型前均可加各种修饰符(signed,unsigned,long,short)
int 类型前可以加signed,unsigned,long,short修饰符 signed int
char类型前可加unsigned和signed修饰符。如果用做字符unsigned,如果用作8个字节的long,用signed
double类型前可以加long修饰符
习惯:一般定义unsigned int 为UINT:typeof unsigned int UINT;
int型使用signed修饰是不建议的
某些实现允许使用unsigned double型,但是降低了代码的可移植行,一般不建议使用
对ANSIC类型的任何扩充都可能在某些编译器上出错
/**/
#include <stdio.h>
void main()
{
/*定义变量并赋初始值*/
int a = 5;
char c = 'a';/*ascii中a对应的数字*/
float f = 5.3;
double m = 12.65;
double result;
/*同类型间进行运算并输出结果*/
printf("a+c=%d\n",a+c);/*将c当作数字进行相加*/
printf("a+c=%c\n",a+c);/*字符型输出*/
printf("f+m=%f\n",f+m);
/*不同类型数据间进行运算并输出结果*/
printf("a+m=%f\n",a+m);
printf("c+f=%f\n",c+f);
/*将上述四个变量进行混合运算,并输出结果*/
result = a + c * (f+m);
1,1 顶端
}
=============================================================
1.常量不占用内存空间,不可变
C语言规定,编译器把数值常量表示成最小兼容类型。缺省情况下,编译器把数字常量放入能够存放它的最小的兼容数据类型中。
如:10-->int类型,60000-->unsigned型,100000-->long型
16位的CPU, 表示的整形的范围 65536,2的16次方
2.C89规定,在人和动作语句之前,在块的开头声明所有局部变量。但在C99以及C++中无此限制(在首次使用前,可以在块的任何位置声明变量)
3.函数体内声明的变量都是局部变量,函数体外声明的变量都是全局变量
4.变量在声明时初始化可以减少程序的执行时间
全局和静态全局变量之在程序开始运行时初始化。局部和静态变量在进入被定义的代码块时初始化
局部变量不经保护实话,初值不确定,知道首次赋值时才有确定值。未经初始化的全局和静态局部变量自动设置为0
若局部变量和全局变量同名,在声明局部变量的代码块中只引用局部变量,不影响全局变量。引用全局变量的方法是在变量名前加两个冒号
#include <stdio.h>
int gv;
void main()
{
int gv = 8;
::gv = gv;/*引用全局变量*/
printf("%d\n",::gv);
}
5.在程序中应减少不必要的全局变量,因为全局变量在程序执行期间一直占用内存空间。并且,若在局部变量可以满足要求时使用全局变量,则函数的通用性变差(因为函数依赖于外部定义的内容)
在程序中大量使用全局变量可能引起未知或非预期的程序错误和副作用(只使用全局变量的标准BASIC语言就是最好的例子)。尤其是在开发大型项目时,一个主要的问题就是在程序的其他地方意外地改变全局变量的值。
6.int型变量与char型变量不是在任何情况下都可以互相代替的,因为ASCII的范围是0到255
7.类型修饰符---const常量修饰符
const型变量的值只随外部事件变化,而不能被程序修改,但能被初始化。编译器会把这类变量放到只读区域中
const通过直接初始化或某些依赖于硬件的方法取得初值:如const int max = 10;
const可以保护函数变量指向的对象,避免它被函数修改。在函数的形参列表中,把指针顶以为const类型,那么函数中的代码就不能修改传入指针指向的实际变量
const也可以使变量不受任何程序的修改。const型变量可以由程序外的成分修改(如硬件设备可以const型变量的值)
jellonwu@jintao :~/Desktop$ vi test3.c
#include <stdio.h>
void main()
{
const int a = 5;
a = 6;
}
jellonwu@jintao :~/Desktop$ gcc test3.c -o test3
test3.c: 在函数‘main’中:
test3.c:5:2: 错误: 向只读变量‘a’赋值
8.类型修饰符-volatile 修饰寄存器变量
volatile告诉编译器,变量的值可能以未在程序中明确的表达方法改变。
volatile int i = 10;/*可变变量,主要用于和硬件打交道*/
volatile的重要性在于防止编译器的自动优化操作
volotile在硬件开发中有很重要的作用
9.存储类型说明符:extern,static
1)在现实工作中,多文件程序和extern声明通常包含在头文件中。
外部变量,表示可以在其他文件中共享,不能修饰局部变量
2)static型局部变量只在它被声明的代码块可见,static型全局变量之在它驻留的文件中可见。本质上,static允许为需要它且唯一认可的函数声明变量,使其在函数调用之间保持变量值的同时又没有意想不到的副作用
static修饰全局变量,只在本文件可见,其他文件不可见,也就是不能被外界访问.
局部变量生命周期为函数开始到结束,static修饰局部变量会改变变量的生命周期,生命周期会变的跟全局变量一样
while(1)
{
int i = 10;
i++;
}
/*每次i都为11*/
while(1)
{
static int i = 10;
i++;
}
/*i==11,12,13,....*/
可以用static局部变量统计函数被调用的次数,就是i++
10.存储类型说明符:auto
比如int a;int b;都是自动型变量
auto型变量都不会被初始化,函数的形参不能被初始化
11.操作符
1)符合赋值:简化了一定类型的赋值操作的编码,被广泛应用于专业C程序的编写,如 a+=10;
2)++和--:在多数编译器中,++和==操作符生成的代码比等价的赋值语句生成的代码运行速度快得多,且目标代码的效率更高。
jellonwu@jintao :~/Desktop$ vi test4.c
#include <stdio.h>
void main()
{
int m = 10;
int n = m++;
printf("m:%d\n",m);
printf("n:%d\n",n);
int x = 10;
int y = ++x;
printf("x:%d\n",x);
printf("y:%d\n",y);
int a = 10;
int b = a--;
printf("a:%d\n",a);
printf("b:%d\n",b);
int c = 10;
int d = --c;
printf("c:%d\n",c);
printf("d:%d\n",d);
}
jellonwu@jintao :~/Desktop$ ./test4
m:11
n:10
x:11
y:11
a:9
b:10
c:9
d:9
3)编译时操作符号:sizeof()在编译时求值
返回其操作数(变量,类型)对应数据类型的字节数。主要用于生成依赖C内设数据类型尺寸的可移植代码
用于计算结构体数组的长度
例子1:sizeof f,sizeof(int)
4)关系和逻辑操作符:它们的运算顺序均低于算术操作符,并且只产生0和1
关系:指各值之间的关系(>,<,>=,<=,==,!=)
逻辑:指如何组合各值之间的关系(&&,||,!)
经验:判断是否相等数字在前,变量在后,例如if(10==a){}
多用括号,说明优先级,例如(10>5)&&(10<9)||(3<=4)
5)位运算(&,|,^(位亦或),~(位取反),>>,<<):C是专门为多数程序设计人物中取代汇编语言而设计的,所以C支持许多汇编操作
位操作只能作用于标准的char和int型数据
.按位与可以作为一种清楚某位的手段(0与任何数均为0)
.或操作可以用于置位(1或任何数均为1)
.亦或用于检查两个操作数的某对应位是否一致,不一致则为1
.移位操作:主要用于对外部设备的输入解码,D/A转换,读状态信息等。也长用语加密子程序
左移(<<):相当于乘以2
右移(>>):相当于除以2
注意:左移并不能恢复右移丢失的信息
sunsigned char result;
int a ,b ,c , d;
a = 2;
b = 4;
c = 6;
d = 8;
result = a&c;
result = b|d;
result = a^d;
result = ~a;
unsigned int a,b,c,d;
int n;
a = 64;
n = 2;
b = a >> (6-n);
c = a << n;
d = (a>>(n-1)|(a<<(n1+1)))