1.字节数:
Char:1个字节
Unsigned:1个字节
Short:2/4个字节
Int:2/4个字节
Unsigned
int:2/4个字节
编译器在32位一下:
Long:4个字节
Unsigned long:8个字节
Float :4个字节
Double:8个字节
《**:不存在无符号的float和double类型
3.补码规则:
正数的补码就为其本身
负数的补码为按位取反加1
4.大端,小端的存储
小端
0x0016F9c0
78
0x0016F9c1
56
0x0016f9c2
34
总结:低地址放低位数据
高地址放高位数据。
大端
0x0016F9c0
34
0x0016F9c1
56
0x0016f9c2
78
总结:低地址放高位数据
高地址放低位数据。
一般存储采用小端存储
Eg:
Int i = 0x12345678;
//首先要转化成占一个字节的类型
If(*(char*)&i=0x12;//
低地址如果存放的是高数据则说明
它是大端否则是小端(栈的生长方向右高地址到低地址)
{
Return
true;
}
Else
{
Return
false;
}
intget_current_sysmode()
{
unionS
{
chara;
intb;
};
unionS
g;
g.b = 0x12345678;
if(g.a
== 0x78)
{
return-1;
}
else
{
return1;
}
}
判断大小端调用实现方法
法2
intmain()
{
inti
= 0x12345678;
if(*(char*)&i==
0x78)
{
return1;
}
else
{
return0;
}
}
5.标识符:不能以数字开头。下划线,字母可开头《一般下划线不合
理,底层程序一般用下划线开头》
关键字不能用做标识符,大小写较敏感,windows大小写不敏感
。
Const
int n=10; “const”为常变量,定义时必须赋值
并且不能改变,C++语法。
6.int
i; i=1;
devc++
vc
Printf(“%d”,i++)
1
1
Printf(“%d”,i++)
2
2
Printf(“%d”,++i)
4
4
Printf(“%d”,--i)
3
3
Int b=(i++)+(++i)+(++i)+(i++);
Printf(“%d”,b);
B=20;
7.拓展
Ctrl+F
查找
Ctrl+H
替换
Ctrl+G
跳转
Ctrl+F8
对齐
Ctrl+Z
结束
Ctrl+C
中断
8.*p在32位的计算机中为4个字符,在64位的计算机中8个字符。
Int/long/short所代表的指针均为4/8个字符。
9.Int
arr【a】;
Int a=10;
不能编译,a应该为常量,在int前加const或定义常熟宏则可以编译(C++语法中const int
a=10,a为常量,C语言中a为常变量)
10.堆是从低地址向高地址申请。
11.若a【10】={1,2,3,4},未被初始化列表指定的数组剩余元素,系统会自动把整形常量初始化为0,字符型初始化为“\0”,指针型初始化为null。
12.#include
#include
int main()
{
char arr[]="afkhjfk";
printf("%d",strlen(arr));
printf("%d",sizeof(arr));
return 0;
}
第一个等于7,第二个等于8;
原因:strlen求字符串长度,sizeof求字符串所占空间的大小。
Char
arr[4]={“a”,”b”,”c”,”d”};
Char brr[]=”abcd”
Printf(“%d”,sizeof(arr));
Printf(“%d”,sizeof(brr));
第一个为4,第二个为5;
Char arr[4]={“a”,”b”,”c”,”d”};只定义了4个字符数组,系统会自动加\0,则打印出来的为abcd+乱码;
若改为char arr[5]={“a”,”b”,”c”,”d”};系统会自动为字符数组赋值\0,则打印为abcd.
13.strset:设置字符串内容为某字符(如:*)
Strchr:指的是若传入字符串中无字母,则输入NULL.
若有此字母,则输入该字母的地址。
Assert(str[]!=0)若不满足()内的就会中断该程序
14.不能做switch()的参数类型是(float,double).
15.不使用其他变量交换a,b的值
a=a+b;b=a-b;a=a-b;
A
= a ^ b;
B
= a ^ b;
A
= a ^ b;
16.解释堆和栈的区别
(1)堆是通过malloc/relloc申请动态空间,
栈:局部变量保存在栈内。
(2)堆:从低地址向高地址生成
栈:与堆相反,从高地址向低地址生成
(3)堆:内存中不连续
栈:内存中连续。
17.在微型计算机中(pc),RAM叫(随机读写存储器)
理论上,64位寻址能力是32位寻址能力的2^(64-1)/
2^(32-1)=2^(32-1)
*********12*34=452是多少进制的算法???
1*6^1+2*6^0=8
3*6^1+4*6^0=22
22*8=176
452=4*6^2+5*6^1+2*6^0=176
18
#define
foo(x) x*3-2
Int
main()
{
Int
a=2;int b=3;
Printf(“%d”,foo(a+b));
Return
0;
}
2+3*3-2=9;
19:函数
(1)全局函数:定义在函数体外部(若不给初值,系统会自动
分0)。
生命周期:从定义开始到全部函数程序结束,一般写在程
序的开始,不写在任意函数体内
(2)局部变量:定义在函数体内部(普通局部变量若不给初始化值,系统会自动分0或者不符合程序要求)
生命周期:从定义开始到所定义的函数结束。
Static存在于全局/静态变量区
20.程序局部变量存在于栈中(stack)
静态变量存在于
数据段/全局变量区/静态变量区
全局变量存在于全局变量区
21.Extern
外部变量声明
22.函数调用与宏之间的优缺点?
函数调用浪费系统资源,可以展开调试。
宏比较节省系统资源,代码较为简单,较易修改,但不容易读,无法展开调用。
22.共用体是构造数据类型,也叫联合体
它使几个不同类型的变量共占一段内存(相互覆
盖),每次只有一个能使用.
结构体则不然, 每个成员都会有存储空间的,可以一起用.
23.数据存放在局部变量,也就是栈中,执行完就会释放,而指针存放在全局变量中,一直到整个程序结束
24. typedef int *p;与 #define int *p;的区别以及它的用法
#define是在预编译时处理的,它只能做简单的字符串替换,而
Typedef是在编译阶段处理的
Eg1: p i,j;
用typedef int *p;相当于
int *i; int *j;
用#define int*p;相当于p=int *
Int *i,j;
//而这个j没有定义会出现错误
Eg2:
Typedef
struct
(STU)
{
Int
num;
Float
score;
}stu;
声明一个结构体,typedef的作用使用stu来代替struct(STU),这个STU(一个名字)可要可不要,这里的stu为结构体类型不是变量名。
***如果没有名字:指定了一个无名的结构体类型,再不能以此结构类型去定义其他的变量
Struct STU
{
Int
num;
Float
score;
}stu;
声明一个叫做STU(类型)的结构体,stu是结构体变量名;
Union 共用体类型
Eg 1:
Union data
{
Int
i;
Char
ch;
Float
f;
}a = { 1 ‘a’,1.5};错误!!!!
不能初始化3个成员,
它们占用同一段存储单元
Union data a = {16}; 正确,对第一个成员初始化
Union data a = { . Ch =’j’};
c99允许对指定的一个成员
初始化。。
Eg 2;
a.ch = ‘a’;
a.f
= 1.5;
A.i
= 40;
完成以上3个赋值运算后,变量存储单元存放的是最后存入的40,原来的‘a’和1.5都被覆盖。
Printf
(“%d”,a.i)
40
Printf(“%f”,a.f)
未知
Printf
(“%c”,a.ch)‘c’
25.#include
Int
main()
{
Short
i;
Scanf(“%d”,&i);
//
Printf(“%d”,i)应该用%hd.
Return 0;
}
26.有符号整形的表示法(如下图1)
答案是255,碰到0时结束
0
-128
无符号整形(如下图2)
27.其它进制转十进制
Eg:11001.118=1*2^4+1*2^3+1*2^0+1*2^-1
1*2^-2+8*2^-3
28. 十进制转其它进制
整数部分倒置求余(从下往上),小数部分乘权值(从上往
下)。
函数名
调用形式
功能
返回值
fgetc
Fgetc(fp)
从fp指向的文件中读入一个字符
读成功,带回所读的字符,失败则返回文件结束标志EOF(-1)
fputc
Fputc(fp)
把字符ch写到文件指针变量fp所指向的文件中。
输出成功,返回值就是输出的字符,输出失败,则返回EOF(-1)
fgets
Fgets(str,n,fp))
从fp指向的文件读入一个长度为(n-1)字符串,存放到字符数组中str中。
读成功,返回地址str,失败则返回NULL
gputs
Fputs(str,fp)
把str所指向的字符串写到文件指针变量所指向的文件中。
输出成功,返回0;否则返回非0值;
Fread(一般用于二进制)
Fread(buffer,size,count,fp)
从文件fp中读取size*count个字节数放入buffer中)
Fwrite(一般用于二进制)
Fwrite(buffer,size,count,fp)
把buffer所指向的空间区域的size*count个字节放入到fp所指向的文件中。
29.**************
Int
main()
{
Int i=10;
Int j=20;
Const int *p=&i;
*p=100;
//因为int*为常变量,*p=100;不能通过,但是p=&j可以通过
P=&j;
*p=200;
}
//
若int* const p=&i;
则*p=100;通过
P=&j;
不通过;
Eg: 1. int const *p;
可以修改指针的值,但是不能修改它所指向的值
2 int *const
p
可以修改指针所指向的值,但不能修改指针的值
3. Int const
*const p;
指针和指针所指的变量的值都不能改变
30.memset;将已开辟的空间S的n个值设为c,它的作用一般用于内存空间初始化。
Memmove:用于从src拷贝count个字符到dest,如果目标区域和源区域优重叠的话,memmove能够保证在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是目标区域和源区域诶有重叠则和memcpy函数功能相同。
Fseek:改变文件的位置标记
Ftell:测定文件位置标记的当前位置。
31.误区
Eg:
#include
Intmain()
{
Printf(“%d”,printf(“%d”,printf(“%d”,43)));
Return0;
}
输出是4321,因为:printf输出43后把它作为返回值给了下一个printf输出的仅仅是它 的个数,所以43
2
1.
32.数组指针
int[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
在C语言中专门用来指向二维数组
Int(*p)[4];
一般用来指向数组(指向包含4个元素的一位数组)
P =
&a;表示指向数组的首地址
P =
a,表示p的值是&a【0】(指向首元素的首地址);
Eg:
int a[4] = {1,3,5,7};
int (*p)[4] ;
printf("%d\n",**p);
指针数组(指针数组是多个指针变量,以数组形式存在内存中
,占有多个指针的空间
以下的例子,,name是个不可知的表示,分别指向name[0],name[1],name[2]
Char *name[n]={“abcde”,””ghijk”,”lmnop”}
Char **p=name;
Printf(“%p”,name);打印的只是指针的地址。系统给它分配的地址。
Eg:
错误的做法
指针数组:一般用来指向字符串;
可以用指向一位数组指针来做
Eg:
int (*p) [3] 数组指针sizeof(p) = 4 ,sizeof(*p) =
12
int *p [3] 指针数组, sizeof(p) = 12 ,sizeof(*p) =
4
char p[2][10] = {"hello","word"};
cout<
char (*str)[10];
cout<
;表示一个二维数组的地址
char *p[2] = {"hello","word"};
cout<
33.static保存在数据段中(影响变量只能在本文件中访问)
extern
(引入外部变量或函数)
34.不用其他的变量数值的交换
Eg:
a和b交换
a = a +
b;
b = a -
b;
a =a -
b;
用位来处理
a =
a^b;
b =
a^b;
a =
a^b;
35 误区
Int i=10;
Double dou =10,10;
(此处分子是浮点型==3.6)
Printf(“%lf”,i+dou+9/5-1.2*3)===17.5
(此处分子是整形=1;)
36.多重if和else的处理
If{ if
}
else
if
If{
elseif
}
每一层都会判断
只要有有一个条件合格则直接跳出
37
Eg: int str(char str[200])
Printf(“%d”,sizeof(str));======4;
首地址会退化成指针,所以返回4.
38.有关地址相减的问题
假定s和p之间有连个元素
Printf(“%d”,p-s);两个指针地址相减得到他们之间的个数
Printf(“%d”,(int)p-(int)s);
它的值为8;
39,误区
char
str[20]={'a','b','c','d','e'};
printf("%d",sizeof(str));==20;
Str中它是按字符来算的,没有在末尾补“\0”,但是字符串不同,字符串会在末尾补”\0”
40.知识点
printf("%p\r\n", (pAry + 1*sizeof(int[5])));1*sizeof(int[5])=====sizeof(int)*5=20;
#include
int main()
{
int arr[5] = {1,2,3,4,5};
printf("%d\n",sizeof(arr));
打印20;算的是整个数组长
所占的空间大小。
//printf(“%d\n”,sizeof(arr[5]));==sizeof(int);
打印4;只是算的一个数所占空间大小,并不是全部
printf("%d\n",&arr);
printf("%d\n",&arr+1);
两个地址相减得到是16
!!&arr+1是越过了这一行(地址不会发生溢出,但它的解引用会发生溢出),所以&arr和&arr+1之间相差了16个字节。
return 0;
}
41.eg:
Char
*pathname=”temp”;
Char
buff[]=”hello”
不能对指针赋值,它保存在全局变量中,可以对数组赋值,它保存在局部变量中。
42.auto和malloc的优缺点
Auto的优点:
1.
不用手动管理
2.
空间占用略小
3.
速度/效率略高
4.
不会产生内存泄漏
Malloc的缺点:
1.
手动释放内存
2.
空间占有略大
3.
速度/效率略慢
4.
不释放会产生内存泄漏
43.
内存所在区域
声明周期
可见范围
作用域
局部变量
栈中
函数内部
函数内部
函数内部
全局变量
数据段/
静态变量区/全局变量区
进程建立起开始,进程结束时中止
整个文件
文件作用域
静态变量
数据段/
全局变量区/静态变量区
进程建立起开始,进程结束时中止
静态局部变量,静态全局变量
外部变量
数据段/
全局变量区/静态变量区
进程建立起开始,进程结束时中止。
通过extern关键字引入的文件,在引入的整个文件可见
44.宏定义(宏不能做递归)
常用的宏有:sprinf,__VA_ARGS__,assert;(已在错误总结中记录)
#include
#include
#define debug_output(format,...)
\
char
out_buf[512];
\
sprintf(out_buf,format,__VA_ARGS__);
\
fprintf("%s",out_buf)
int main()
{
printf("%s", debug_output("%s,%d","hello",10));
return 0;
}
在宏定义的使用中,易出错的点
#define max( a, b) ((a)>(b))
? (a) : (b)) 从右至左。
X =5;
Y = 8;
Z= max(x++,y++);
Prinf(“x
= %d,y = %d,z = %d\n”,x,y,z)
这块应该值得注意,如果按照正常的函数调用的话,打印z=8;
但是如果采用宏定义中的max则打印x = 6,y = 10,z
= 9;第一个表达式是一个条件表达式,用于确定另两个表达式中的哪一个,剩余的那个表达式将不会执行。宏定义只是简单的进行替换,并不会去
判断,第一个表达式是以一个条件表达式,
#define Inc(x) ++x
int main()
{
int arr[5] = {1,2,3,4,5};
int i = 0;
arr[Inc(i)] = arr[Inc(i)]+10;
for(int j = 0; j < 5; j++)
{
printf("%d ",arr[j]);
}
return 0;
}
这块打印1,2,12,4,5
注意#define只是进行简单的宏替换
也就是i++了两次
宏定义中
Eg:
#define
str(x)
#x
这个定义x讲打印出来的是一个字符串,在x前面加一个‘#’。
#define str(s1,s2)
s1##s2
这个定义的意思是把s2连接到s1的后面,形如s1s2.
45.易出错点
Int i =10 ;
Printf(“%d”,sizeof(i++));
此处打印4
Printf(”%d”,i);
此处打印10
Sizeof测内存空间所占的大小,在编译的阶段只是把4push并没有++,也就是说直接忽视了i++,仅仅测它所占的大。