一、C语言数据存储和规范
学习目的:
掌握C语言基本数据类型(基本数据类型、变量的常量、表达式和运算符。)
标识符:C语言中的变量、常量、函数等命名
命名规范-标识符
标识符:C语言中的变量、常量、函数等命名。
原则:
1.命名清晰,明了,有明确的含义。尽量使用完整的单词或大家基本可以理解的缩写。
2.第一个字母不能是数字(其他为字母下划线和数字的组合)
3.标识符应当采用英文单词或其组合。
错误命名:3ab,&cd、sum%4
不好的命名:int a ,Age1 ,XueshengAge;
好的命名 :int StudentAge; avg 、count等
命名规范-变量名
1.不同作用域变量的命名
1)局部变量一小写字母命名
2)全局变量以首字母大写方式命名(骆驼式)
3)定义类型和宏定义常数以大写字母命名;
变量的作用域越大,他的名字所带有的信息就应该越多。
实例:
局部变量:int student_age
全局变量:int StudentAge
宏定义常数:#define STUDENT_NUM 10
类型定义:type INT16S int
匈牙利命名法
匈牙利命名法是一种命名约定。匈牙利命名法把变量的类型等信息编码在变量名中
指针变量的命名
对于指针的定义,名称大小写根据指针为全局/局部变量来定,但指针名必须以小写的"p"开头。
实例:
int *pDay,//全局指针
int *pday;//局部指针
int **ppDay;//指针的指针。
命名规则-函数名
函数名的命名应象全局变量一样采用首字母大写方式(骆驼式)。
函数名的开始应以" 模块名_ "的格式注明函数所属模块。
实例:
KEY.C模块的函数
void KEY_Init(void);
void KEY_StartScan(void);
void KEY_StopScan(void);
TMR.C模块的函数
void TMR_Init(void);
void TMR_Start(TMR_ID tmr);
void TMR_Stop(TMR_ID tmr);
-常量
整型常量
十进制整常数:没有前缀,其数码为0-9。例如65535,-568
八进制整常数:以0开头,其数码为0-7。例如015
十六进制整常数:以0X或0x开头,其数码为0-9,A-F或a-f。例如0x2A
长整型数:整型常数后缀为L或l。例如358000L
无符号数:整型常数后缀为U或u。例如158u
实型常量的形式
小数形式:必须有小数点,小数点前后不能同时没有数字。
指数形式:aEn(其中a表示十进制数,E阶码标志,n阶码)。E前E后必须有数字,E后必为整数,可以带符号。例如2.1E-3、5E8
字符常量:
用单引号''括起来的一个字符。包括普通字符常量和转义字符。
实例:
普通字符常量:如'a'、'A'、'1'。
转义字符:由一对单引号引起来的以\开头的若干字符的组合。如'\n'表示回车换行、'\\'表示反斜线符、'\''表示单引号符、'\"'表示双引号、'\ddd'表示八进制数、'\xhh'表示十六进制数。
变量类型
-
整型:短整型、长整型、无符号整型
-
实型:双精度、单精度
-
字符型:可以跟整型互换
类型 | 所占 位数 | 所占 字节数 | 类型 | 所占 位数 | 所占 字节数 | |
short | 16 | 2 | unsigned long | 32 | 4 | |
int | 32 | 4 | char | 8 | 1 | |
long | 32 | 4 | float | 32 | 4 | |
unsigned short | 16 | 2 | double | 64 | 8 | |
unsigned int | 32 | 4 |
变量定义
-
变量先定义后使用
-
定义格式 :[修饰符] <类型> 变量名[=表达式];
-
修饰符:auto、static、register、extern、volatile、const等
表达式可以是变量、表达式或者常量
ASCII码
-
'0'的ASCII码值为48;'A'的ASCII码值为65;'a'的ASCII码值为97。
-
大写字母与小写字母的ASCII码值相差32。
实例:
int main()
{
char c1,c2;
c1='A'+'8'-'4';
c2='A'+'8'-'5';
printf("%c,%d\n",c1,c2);
}
进制转换
-
十进制转换成二进制、八进制、十六进制:将十进制的数字除以2(8、16),得到的商数继续除以2,直到商为0,然后将各次相除所得的余数从后往前排列。
-
二进制、八进制、十六进制转换成十进制:将二(八、十六)进制数的每一位数从高位到低位乘以2的n-1次幂,n为该位所在的位数。
-
二进制与八进制之间的转换:每个八进制数字转换成3位二进制数字。
-
二进制与十六进制之间的转换:每个十六进制数字转换成4位二进制数字。
-
实例:
#include <stdio.h>
int main()
{
int a=200,b=010;
printf("%d%d\n",a,b);
}
C程序存储布局-编译器
-
编译器:是一个程序,它读人用某种语言(源语言)编写的程序并将其翻译成一个与之等价的另一种语言(目标语言)编写的程序。
源程序 到 | 编译器 到
| 目标程序 |
报错 |
编译器工作原理
一个语言处理系统
编译器各个阶段
Gcc编译流程
Gcc编译分为4个流程
-
预处理(替换,将一些宏定义库函数替换到代码中去,'把调用的函数取出来')p.i
Gcc –E hello.c –o hello.i
-
编译(检查语法和词法的错误''将预处理之后的代码进行词义分析,语法检查')并生成汇代码p.i
gcc –S hello.i –o hello.s
-
汇编(将汇编语言转换为二进制码)p.o
gcc –c hello.s –o hello.o
-
链接(生成可执行文件 j将生成的二进制文件转换为计算机可执行的文,调用malloc件)
gcc hello.o –o hello、
存储布局
由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。
C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。在程序运行时又会产生其他几个部分,各个部分代表了不同的存储区域:
我们编写一段代码,每一个变量都有他自己所在的存储位置(栈、堆、未初始化数据段、初始化数据段、代码段(正文段))。
*只读数据段(RO data):只读数据段是程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可
*堆(heap):程序员手动分配内存的变量、调用malloc、calloc之类手动分配内存的函数。堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。
*未初始化数据段(BBS):又称未初始化全局变量区。未初始化数据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间
*初始化数据段:已经初始化全局变量区
*代码段(code):一些条件语句,代码存放在初始化数据段。代码段由程序中执行的机器代码组成。在C语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,CPU的程序计数器指向代码段的每一条机器代码,并由处理器依次运行
*栈(stack):一般存储局部变量。栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。它的空间比较小,它是由系统自动分配内存和释放内存的。
int a;定义a;系统分配4个字节的空间给a。
一般局部变量都是存放 在栈。
实例:
1 int a = 0; //全局初始化区,.data段 2 3 static int b=20; //全局初始化区,.data段 4 5 //static 静态的意思,作用,变量b,它被限定在本文件中,不能被其他文件使用。一般来说,它存储在初始化数据段 6 7 8 9 char *p1; //全局未初始化区 .bss段 10 11 const int A = 10; //.rodata段 12 13 //const表示只读的意思,就是说A的值不能改变,或者说A是一个常量 14 15 16 17 void main(void) 18 19 { 20 21 int b; //栈 22 23 char s[] = "abc"; //栈 24 25 char *p2; //栈 26 27 static int c = 0; //全局(静态)初始化区 .data段 28 29 char *p3 = "123456"; //123456\0在常量区,p3 在栈上。 30 31 char *p="wangling";//这里是定义一个字符串常量,字符串常亮不可改变 32 33 34 35 p1 = (char*) malloc(10);//分配得来的10和20个字节的区域就在堆区 36 37 38 39 p2 = (char*) malloc(20); 40 41 strcpy(p1, "123456"); //123456\0 在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方 42 43 }
定义在一个函数(就是一个功能模块)中的局部变量,在函数结束时就不能再次使用。因为他已经被系统回收了
定义的全局变量存放在全局数据段,(总之就是不在栈中),他的作用范围是在整个程序的。
所有的指针都占4个字节。