您的位置:首页 > 运维架构 > Linux

linux c学习

2016-07-10 17:01 471 查看
1 只在头文件中作声明
2. 补码是负数真正的物理存储格式
3. double f2 = 1.0;

printf("%lf", f2);
long double f3 = 1.0;

printf("%Lf", f3); // 注意下,长双精度不是 %llf
,而是 %Lf
4. 字符9和数字9。字符9存储的是ascii码,数字9存储的是9的二进制表达式。
5. 循环条件是 getchar() != '\n'
,这句话的意思是,用getchar()
这个函数去缓冲区拿取数据,每次去拿一个字符,只要不是回车符 '\n'
,就继续循环,直到拿到回车符为止。为什么是回车符呢?因为用户再输入的时候,最后一定是按了一下回车键来结束输入的(本质原因是标准输入流是行缓冲类型的),因此在缓冲区中的数据一定是以回车符
'\n' 作为结尾的,当我们用 getchar()
获取到回车符时,就表示缓冲区就被我们清空了!
6. 位运算符
7. Switch中表达式的值必须是整型
8. Goto语句,在linux内核中常出现在跳转错误处理的代码中
9. 内联函数就是典型的用空间换取时间的例子
10. 回调函数
11. 函数指针有两种用法,第一是在结构体中实现面向对象,实际就是用函数指针指向操作结构体数据的函数。
signal(SIGINT, func); // 捕捉SIGINT,顺便告诉内核其响应函数是func,函数名func就是函数指针
这样,当进程收到SIGINT时,就会进入内核,执行内核的相关动作,然后内核按照用户层提供的func这个函数指针,回到用户控件调用func函数,因此这个函数也被称为回调函数,回调函数实现了不同的程序模块由不同的人开发,而且又可以协调合作的目的。
20.

extern int a; //声明一个“别处”定义的全局变量,此处extern不可省略

extern int f(); // 声明一个“别处”定义的函数,此处extern可省略
“别处”的意思仅仅指不在当前位置,可能是别的文件,也可能是该文件的其他地方。注意,如果声明的是一个变量,那只能是全局变量,局部变量不能用extern来声明。
被声明为register类型的变量一般是因为程序对其读写性能很敏感,比如在底层操作系统中,要频繁地对某个变量进行读写,而且这个变量的读写速度直接影响到了程序的性能,是整个程序的热点也是瓶颈,那么就很有必要将其声明为register存储型。
auto这个关键字就像signed一样,一般都会被省略。因为auto的含义是将一个变量存储在“自动”存储区,所谓的自动存储区就是进程的栈空间,而普通的局部变量默认就是存储在栈空间的,所以没有必要再用auto来修饰。而auto又不能修饰全局变量,因为全局变量一定是存储在静态区的。



注意上图中的用户栈和运行时堆,它们是会在程序运行时动态变化的,里面的变量时而诞生时而消亡,具体而言指的是:在栈中存在的变量都是局部变量(包括函数的形参),其生命周期是从定义它的语句开始,到离开其作用域为止。在堆中存在的变量都是所谓的动态内存,这些内存的生命周期都是由程序员指定的,从malloc()分配某块内存开始,到free()释放这块内存结束。堆和栈分别向上和向下的箭头代表它们在内存中的增长的趋势。
读写段(即静态区)、代码段、常量区等内存区域则在程序运行期间是“稳定”的,即不会被释放,这些区域的内容将会被一直保留,直到整个程序退出为止。
以下情况不适合使用局部变量:
第一,巨大的变量。比如一个2000个元素的数组,那么大的数据量很有可能使得栈溢出。
第二,动态的数据。比如一个动态增长的链表,虽然程序运行初时不大,但是程序无法预料以后该链表的节点数目,像这种动态的数据也不能用栈空间来存放。
由于栈空间的分配跟释放是由系统自动完成的,其执行效率高速度快,所以适合用来存放一些可以被临时释放的数据。
而堆空间,则是程序运行时大部分数据的真正的演练场,这部分空间的分配和释放完全由程序员来控制,因此也叫做内存的自由区,自由意味着谨慎,如果只分配不释放,内存就会很快被用光,因此,堆空间是一个需要你更加负责任的地方。
动态内存的使用有几点要注意:
1,使用完毕之后,一定要释放。
2,如果不释放,那么该块内存只能等到程序全部退出之后才能被释放。
3,free()
只能释放动态内存(即由malloc( )
或者 calloc()
或者 realloc()
分配的内存)。
4,访问动态内存的唯一方式是采用指针,因为动态内存是匿名的。
21.
struct student Jack = {

.name = "Jack",

.score = 88.5,

.age = 20

};
一个有趣的地方是:数组不能这样直接赋值,但是如果两个结构体里面包含数组,结构体却可以直接赋值。
乍看起来,一个结构体变量的大小,就应该等于其各个成员的大小之和,但事实并非如此,各个成员之间,会常常由于所谓的“地址对齐”的问题而被填充一些零,因此一般来说一个结构体的大小往往要大于其各个成员的大小之和(至少是相等)。
1,如果一个变量的长度 length <= CPU的字长,那么要求该变量自然对齐
2,如果一个变量的长度 length >= CPU的字长,那么该变量只要按CPU的字长对齐即可。
而联合体完全不同,联合体的所有成员的起始地址都是一样的,换句话讲,它们将来将会相互覆盖!最后对哪一个成员赋值,哪一个成员就有效,其他的统统失效。结构体的大小计算比较复杂,要考虑地址对齐,联合体的大小非常简单,决定于最大成员。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: