C/C++语言复习一

1,原码、反码和补码

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

整数中正数的原码、反码和补码完全相同;

负数的反码是将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0);

负数的补码是将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1;

数0的反码也有两种形式,即:[+0]反=00000000B,[- 0]反=11111111B,数0的补码表示是唯一的0 = 00000000B。

2,类型转换

     浮点型转换为整形:double a = 3.14;
short b = a;
printf("%d, %d", b, a);输出3,1374389535;

 原因:浮点型数据的内部存储方式是一指数形式存储的,所以表示的范围要比相同位数的整形大得多。

3,数据类型

它决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围,以及变量能参与的运算。

变量就是一段内存空间,数据类型就是固定大小内存块的别名;


一个浮点数由三部分组成:符号位S、指数部分E(阶码)以及尾数部分M。

  1. 单精度浮点数(float)总共用32位来表示浮点数,其中尾数用23位存储,加上小数点前有一位隐藏的1(IEEE754规约数表示法),2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位。考虑到第7位可能的四舍五入问题,所以单精度最少有6位有效数字(最小尺寸)。 

  2. 同样地:双精度浮点数(double)总共用64位来表示浮点数,其中尾数用52位存储,     2^(52+1) = 9007199254740992,10^16 < 9007199254740992 < 10^17,所以双精度的有效位数是16位。同样四舍五入,最少15位。

4,预编译,编译,汇编,链接

预编译过程主要处理源代码文件当中的以#开头的预编译指令,比如#include就是把头文件插入到这个位置 #define就是把所有的宏定义展开,还有就是删除所有的注释;

编译就是把i文件编译成为汇编代码文件;

汇编就是将汇编语言的代码文件转变成机器语言,只是对照汇编语言的指令和机器语言一条一条翻译过来。

链接将各个目标文件绑定在一起,形成一个独立而完整的可执行程序。

5,字符串

字符串常量的本质是这些字符中首字符存放的地址。

6,const

int const *p1;这是一个指向整型常量的指针;

int * const p2;这是一个指向整形的常量指针。

7,链接属性

external属性的标识符无论声明多少次、位于几个源文件,都表示同一个实体。如果a具有exter属性,static int a;则a具有internal属性;是变量或函数为这个源文件所私有

internal属性的标识符在同一个源文件内声明多次表示文件中的同一个实体,位于不同源文件的声明则分属不同的实体;

8,内存四区(堆区,栈区,代码区,全局区:常量和全局变量)

a) 主调函数可把堆区、栈区、全局数据内存地址传给被调用函数

b) 被调用函数只能返回堆区、全局数据

c) 指针做函数参数,是有输入和输出特性的。

9,static

当修饰函数或代码块之外的变量时,将标识符的链接属性从external改为internal,存储类型和作用域不受影响,只能在声明它们的源文件使用;

当修饰代码块之内的变量时,static修改变量的存储类型,从自动变量改为静态变量,在整个程序执行期间一直存在,而不是代码块执行时创建,执行完销毁。

10,指针

指针的步长,根据所指内存空间类型来定。

[]怎么理解,只不过是c++编译器帮我们程序员做了一个*p的操作 buf[i]-->buf[0+i]-->*(buf+i);

间接赋值是指针存在的最大意义,用n级指针(通常是形参,)去修改n-1级指针(通常是实参)的值

二级指针三种内存模型:char *p[] = {"123", "456"};char a[][4] = {"123", "456"};char **b = (char *)malloc(sizeof(char *)*3);for(int i = 0; i < 3; ++i){p[i] = (char *)malloc(4*sizeof(char));}

11,数组

int a[5] 一维数组名代表数组首元素的地址;int a[5] ===> a的类型为int*

二维数组名同样代表数组首元素的地址;int b[2][5]===>b的类型为int(*)[5],二维数组名是一个数组指针;

C语言中只会以机械式的值拷贝的方式传递参数(实参把值传给形参);一维数组作函数参数退化为指针,二维数组作函数参数退化为数组指针;

void f(int a[5]) ====void f(int a[]); === void f(int* a);

void g(int a[3][3])==== void g(int a[][3]); ==== void g(int (*a)[3]);

一维数组 char a[30] -> 指针 char*

指针数组 char *a[30] -> 指针的指针 char **a

二维数组 char a[10][30] -> 数组的指针 char(*a)[30]

12结构体

浅拷贝深拷贝:两个结构体变量之间可以copy数据,这个是c编译器给我提供的行为,我们要顺从,提供的是浅copy

void  copyObj02(struct  Teacher *from, struct  Teacher *to)

{

memcpy(to, from, sizeof(struct  Teacher));

}

void  copyObj03(struct  AdvAdvTeacher *from, struct  AdvAdvTeacher *to)

{

memcpy(to, from, sizeof(struct  AdvAdvTeacher)); 

to->a_name = (char *)malloc(128);//深拷贝

strcpy(to->a_name, from->a_name);

}


如果在被调用函数里面的临时区(栈)分配内存,主调用函数是不能使用的。


发布了30 篇原创文章 · 获赞 13 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qiaominghe/article/details/50659175