·一般的程序如下:
程序 = 数据结构 + 算法
数据结构含有基本数据和复杂数据,即我们将要交给计算机运算的量
因为数据量 ----> 大小 ----> 存储空间
所以在高级语言中要合理规划存储空间,变量(容器)大小,也就是要合理选择变量类型。
8bit 16bit 32bit 32bit 64bit 96bit/128bit(大小取决与系统)
char short int int float double long double
1字节 2字节 4字节 4字节 8字节 12字节/16字节
有符号: char A; -----> 最高位为符号位,精度减半
无符号: unsigned char A; -----> 没有符号位,精度完整
//定义一个char型变量A
char A;
//第一给A赋值,初始化
A = 49;
A = '1'; ---> ASCII 码 ‘1’ ------> man ascii ----> 每个ascii 字母对应这一个整型量
∴A = 49;等价与A = '1';
有符号 : 1 ---> 0000 0001 -----> 最高位为符号位 : 0 --> 正数 1 ----> 负数
-1 ---> 1000 0001 -----> 最高位为符号位 : 0 --> 正数 1 ----> 负数
·故有符号char数值范围:-128 ~ 127
------------------------------------------程序的空间使用---------------------------------------------
#include
char A;
short int B;
int C;
float D;
double E;
long double F;
int main()
{
return 0;
}
分析:
(1)在程序中定义了全局变量(在文件中,函数体外定义的变量,作用范围为整个文件),是静态变量
★已初始化变量占用文件的存储空间(影响文件的大小)
★未初始化变量不占用文件的存储空间(不影响文件的大小)但是占用符号
(2)在函数中定义了局部变量(作用范围为该函数,随着函数的运行而开辟空间,随着函数的退出而回收空间),是动态变量
★变量不占用文件的存储空间(不影响文件的大小)
nm 结果: ------> 当前程序中,变量的存储地址
0804a05c B A
0804a034 B B
0804a058 B C
0804a030 B D
0804a050 B E
0804a040 B F
地址: 0804a040
B : BSS 未初始化的数据
A-F : 变量名
readelf filename –a读取elf可执行文件的内容信息
△readelf重要字段介绍
1) 文件头(ELF Header) ----> 每种类型的文件都有头信息。
2) 段信息(Section Headers) ----> 当前程序的数据与代码的分类存储区域
.text --->程序的代码位置
.rodata --->只读数据段,为常量
.data --->已初始化可读可写的数据
.bss --->未初始化的数据
3)符号表(Symbol table) -----> 变量名,函数名 都属于一种符号。
E.g:
Value Size Type Bind Vis Ndx Name
0804a050 8 OBJECT GLOBAL DEFAULT 25 E
Value : 地址值
size : 占用的存储空间
Name : 符号名
------------------------------------------运算符-----------------------------------------------------
<1>赋值运算 = -------> 右值必须与左值类型相等,同时左值不能为常量
A = 1; ----> 赋值表达式
A = add(); ---->add()返回的值赋给变量A
赋值形式(1)
int x;
x=1;
赋值形式(2)
int x=1;
int y=2;
赋值形式(3)
int x=1,y=2,z;
<2>逗号表达式: A = (z=x+y,y=5,y+3); ---> 结果等于最后一个表达式的值
5 = A; 错误
A = 5;
<3>常变量 ----> 该变量装载的数值是不可以修改,只能在定义时初始化。
const int A = 10; ---> 变量A 用于等于10 (常量)
A = 5; 错误
编译警告: error: assignment of read-only variable ‘A’
------------------------------------------------算数运算符---------------------------------------------------
<1>算数运算: + - * / %
需要特别强调:精度与数据类型
int B = 3/2; ====> 1.5 ----> int ----> 取整型部分 ---> 1
解决方案:
float B = (float)3/2; -----> 类型强制转换 ----> 3 使用浮点类型进行运算 --->右值为1.500000
float B = (float)(3/2); -----> (3/2) 的结果(整型结果为1)使用浮点类型进行运算 --->右值为1.000000
<2> 强制类型转换: 当默认的初始类型不能满足数据的装载需求时,进行强制变更(更变装载空间)
格式: 在原始数据前,使用()运算符进行类型强制声明。E.g: int a=2,b=3; float B = (float)b/a; ------> 作用范围为临时转换
<3> 取模运算(取余) ----> %两边需为整型数
int A = 3%2; ----> 余数1 ----> A = 1;
%举例应用:
123 取个位数:
int A = 123%10
123 取十位数:
int A = (123%100)/10
<4> 自增自减:
A++ A-- //后操作 ----> 先将A的值参与运算,后加减
++A --A //前操作 ----> 先加减再运算
----------------------------------------------关系运算符-----------------------------------------------
△对量进行判断
关系运算符有:
> >= < <= != ==
·结合判断表达式:
if(a > B)
if(a != B) ---> a 不等于 B
if(a == B) ----> 判断a与B的值是否相同 ----> 只针对整型量 ----> 结果是布尔值 ---> 真或者假
if(a = B) ----> 赋值语句 ---> 一般为真(遵循赋值的格式前提下,左值与右值等价)
------------------------------------------------逻辑运算符--------------------------------------------------
△对条件进行判断
逻辑运算符有:
! && ||
·结合判断表达式:
if( !条件1 ) -----> 当条件1为假时, “ !条件1” ----> 为真
一般用于判断某个结果是否为空 ---> 空值对应 0 ---> 为假
if( 条件1 && 条件2 ) -----> 当条件1为真时, 同时条件2也为真 ----> 整个表达式为真,否则为假
一般用于必须条件1 跟条件2 都同时成立时
if( 条件1 || 条件2 ) -----> 当条件1为假时, 条件2为真即可 ----> 一个表达式为真整个表达式为真;两个条件都不成立时为假
一般用于只要条件1或条件2 有一个成立时
---------------------------------------位运算符----------------------------------------------------------
位运算符有:
& | ~ ^ << >>
(1)& 操作:
0 & 3 ----> 0
00
* 11
00
(2) | 操作:
0 | 3 ----> 3
00
+ 11
11
(3) ~ 操作
unsigned char A = 1 ----> 000000001 ----> ~A ----> 11111110
(4) ^ 操作 ----> 对应位相同为0,不同为1
0 ^ 3 ----> 3
00
♁ 11
11
(5) << >> 操作
获取二进制A的第四位:
A = 1001 0100
char B = (A >> 0x04) & 0x01;
分解:
(A >> 0x04) -----> 0000 1001
& 0x01 -----> 0000 1001 & 0000 0001 -----> 1
★常用于将字符型组合成整型:
E.g:
char A,B,C,D;
int E;
E = A << 24 | B << 16 | C << 8 | D;
----------------------------------------条件运算符----------------------------------------------
A ? B : C;
A成立 ,则执行B ,否则执行C;
------------------------------------------sizeof-----------------------------------------------
sizeof( A ) ----> A 可以为变量名 或者 类型名
返回当前A占用的空间的大小 n 字节
-------------------------------------------复合运算符----------------------------------------------------
位运算符有: -= += *= /= %=
<<= >>= |= &= ^=
将赋值运算符结合算数运算符或者位运算符
E.g:
A = A - 1; ----> A -= 1;
---------------------------------------------格式化IO-------------------------------------------------------
(1)printf家族:
printf(" ...%d..%c.. ",x,y); ----> 往标准输出中输出指定内容,配合相应的格式化输出的标识符★需要注意输出的精度(精度截取)
int printf(const char *format, ...);
int sprintf(char *str, const char *format, ...);
int sprintf(char *str, const char *format, ...); ----> 往指定str字符串空间中输出指定内容,配合相应的格式化输出的标识符
<1.1>char buf[10];
char a=5;
sprintf(buf, "hello %d",a);
-----> "hello 5"
<1.2>int snprintf(char *str, size_t size, const char *format, ...);
char buf[10];
char a=5;
snprintf(buf, 10 ,"hello %d 123456789",a); -----> "hello 5"
(2)scanf家族:
scanf("%d",&a);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
★注意: 输入缓冲
这里要说明scanf是有返回值的,其返回值即为scanf正确读取的变量的个数。
int a,b,c;
scanf("%d",&a); ----> 输入1个整数 ----> 则scanf读取成功,返回值:1;
scanf("%d %d %d ",&a,&b,&c); ----> 输3个整数 : 15 16 17 ----> 则scanf读取成功,返回值:3;
scanf("%d,%d,%d ",&a,&b,&c); ----> 输3个整数 :15,16,u ----> 则scanf读取成功,返回值:2; ----> 缓冲中残留u
★清除缓冲区的方法:
while( getchar() != '\n' ); ---> 一直获取输入缓冲中的字符,直到换行符为止。
文章评论(0条评论)
登录后参与讨论