《深度探索C》笔记
最名不副实的关键字 static
这个关键字在C语言里面有两个作用,C++对这个关键词进行了扩展。
1:修饰变量,又分为局部变量和全局变量,被修饰的变量都存储在静态的内存区域。 修饰静态变量,那么只有在这个文件内可以引用它,在其他文件里面即使使用extern也不能进行访问。所以一般是放在文件头部分。 修饰局部变量,只有在定义的函数内访问,函数外不能访问,即使是在同文件内。
2:修饰函数,在函数前面添加static,那么这个函数只能在该文件内使用。这样,不同人编写的函数,如果不在同文件内,可以不用担心函数名字 相同。
main.c
int main()
{
Func();
reutrn 0;
}
Def.c
static void Func()
{
printf("Func calledn");
}
编译: gcc main.c Def.c -o main 链接错误
变量的命名
min-length&&max-information
低精度数据向高精度数据扩展。
被冤枉的关键字 sizeof 用法:sizeof(int), sizeof(i), sizeof i;
if ,else float类型值与0值比较,定义一个很小的数,在某个范围内。同时不要在一个很大的浮点数和很小的浮点数之间进行运算。
循环注意点
嵌套循环中,长循环放在内,短循环放在外面,这样可以减少cpu跨切循环层的次数,利用cpu cache。 循环里面的代码尽量短,一般不超过20行。如果不行就改为循环调用函数。
void
主要作用在于对函数参数的限定和函数返回值的限定。不能对void进行算法操作。
const
修饰指针的时候的记法,就近原则。 const int *p ; p可变,指向的对象不可变 int const *p ; p可变,指向的对象不可变 int* const p; p不可变,指向的对象可变
struct 和class的区别
在C++中struct关键字与class一般可以通用,一个区别就是struct的成员默认情况下是public的,而class的是private的。
union
一个union只配置一个足够大的空间来容纳最大的数据成员,union的作用在于压缩空间。
存储的大小端:
union
{
int i;
char a[2];
}*p,u;
int main()
{
p=&u;
p->a[0]=0x39;
p->a[1]=0x38;
printf("%dn",p->i);
PrintBinary(14393);
PrintBinary(56);
PrintBinary(57);
if(CheckSystem()==1)
printf("Little endiann");
else
printf("Big endiann");
return 0;
}
11100000111001
111000
111001
Little endian 低字节存储在低地址
指针,访问内存的钥匙
前段时间听过一个面试题,就是如何读写某人地址,答案就是指针?
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0;
int* pp=&i;
printf("%xn",pp);
int* p=(int*)0x12ff60;
printf("%xn",p);
*p=1;
printf("%dn",i);
getchar();
return 0;
}
这段代码在vc中编译是能够运行的,但是在gcc中不行,gcc中编译后i的地址并不是固定的,这样直接给指针赋值,写指向的地址出现访问越界。
a和&a的区别
int main()
{
int a[5]={1,2,3,4,5};
int* ptr=(int*)(&a+1);
int* p=(int*)(&a);
printf("%xn",ptr);
printf("%xn",p);
printf("%d,%dn",*(a+1),*(ptr-1));
return 0;
}
bfeae860 bfeae84c 2,5 说明ptr和a的地址相差5*4=20个byte。 定义数组int a5; a表示的是数组中首元素的地址,&a才是数组的首地址,两者的值是一样的,但是意义却不同。
数组当作函数参数传递
传递的是指针,也就是数组的地址,但注意如果把指针本身传递进函数的时候进行了数组的拷贝,传递的是一个拷贝。
void func(char* p)
{
char c=p[3];
*(p+3)='X';
printf("%cn",c);
}
int main()
{
//char* p="abcdef";
char p[]="abcdefg";
func(p);
printf("%sn",p);
return 0;
}
注意上面的区别,如果是char* p=”abcdef”,那么p为main函数的局部变量,”abcdef”的存储空间在静态内存中,func函数中可以通过指针p去访问其内容, 但如果改变其内容会发生访问越界。而char p[]=”abcdefg”,其数组的内容是在栈上。
内存管理
静态区:保存自动全局变量和 static 变量(包括 static 全局和局部变量)。静态区的内容 在总个程序的生命周期内都存在,由编译器在编译的时候分配。 栈(堆栈):保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容 也会自动被销毁。其特点是效率高,但空间大小有限。 堆:由 malloc 系列函数或 new 操作符分配的内存。其生命周期由 free 或 delete 决定。 在没有释放之前一直存在,直到程序结束。其特点是使用灵活,空间比较大,但容易出错。






七月 21st, 2010 at 3:36 下午
a和&a的区别
这个题目我觉得应该是int a[5]={1,2,3,4,5};这里的a的type是int[5]。
按照C语言标准,&a的type就是int (*)[5],就是一个指向int[5]的指针,所以&a+1就指向了a之后20个byte了。而直接在a上向算法运算a的type就退化成了int*。
c99:
Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.
[回复]
七月 22nd, 2010 at 8:23 上午
看来得好好看看标准
[回复]