标签:
笑话一枚:
程序员 A:“哥们儿,最近手头紧,借点钱?”
程序员 B:“成啊,要多少?”
程序员 A:“一千行不?”
程序员 B:“咱俩谁跟谁!给你凑个整,1024,拿去吧。”
========================= 我 是 分 割 线 =========================
C语言允许直接访问物理地址,可以直接对硬件进行操作,非常适合开发内核和硬件驱动。
书上看来一句话:普通人用 C 语言在 3 年之下,一般来说,还没掌握 C 语言;
5 年之下,一般来说还没熟悉 C 语言;10 年之下,谈不上精通。
学习一门语言最基本的还是要多码码,多调试,必要的时候可以用小黄鸭调试法。
多思考,遇到问题自己先尝试深入研究和解决。
下面的笔记来自《C语言深度解剖》
定义、声明最重要的区别:定义创建了对象并为这个对象分配了内存,声明没有分配内存。
一般的变量使用驼峰命名法(CamelCase),加上必要的前后缀。
所有宏定义、枚举常数、只读变量全用大写字母命名,用下划线分割单词。
c语言有4种存储类型:auto, extern, register, static,定义变量的时候只能指定其中的一种类型。
而变量分配在内存存储空间的有:BSS区、数据区、栈区、堆区。
也有变量不在内存中:register 变量可能不存放在内存中,所以不能用取址运算符“&”来获取 register 变量的地址。
第一个作用:修饰变量。静态全局变量和静态局部变量,都存在内存的静态区。
静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用 extern 声明也没法使用他。
静态局部变量,在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他函数也用不了。
第二个作用:修饰函数。不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。
好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
int i=0;
A),sizeof(int); B),sizeof(i); C),sizeof int; D),sizeof i;
这里只有选项C是错误的,因为 sizeof 在计算变量所占空间大小时,括号可以省略,而计算类型大小时括号不能省略。
还有就是 sizeof 不怕地址越界,它只计算变量类型占空间大小,不会去访问变量的地址,也就不清楚人家存不存在了。
1.下面的代码输出是什么?为什么?
void foo(viod) { unsigned int a = 6; int b = -20; (a+b>6)?puts(">6"):puts("<=6"); }
2.下面的代码的结果是多少?为什么?
intmain() { char a[1000]; inti; for(i=0; i<1000; i++) { a[i] = -1-i; } printf("%d",strlen(a)); return 0; }
void 的字面意思是“空类型”,void *则为“空类型指针”,void *可以指向任何类型的数据。
任何类型的指针都可以直接赋值给 void *,无需进行强制类型转换:
void *p1;
int *p2;
p1 = p2;
case 后面的值只能是整型或字符型的常量或常量表达式。
定义 const 只读变量,具有不可变性。const 修饰的仍然是变量,只不过是只读属性罢了,不能当作常量使用。
const 修饰符也可以修饰函数的参数,当不希望这个参数值被函数体内意外改变时使用。
const的作用:节省空间,避免不必要的内存分配,同时提高效率
编译器通常不为普通 const 只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。
volatile修饰的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
先看看下面的例子:
inti=10;
intj = i;//(1)语句
intk = i;//(2)语句
这时候编译器对代码进行优化,因为在(1)、(2)两条语句中,i 没有被用作左值(没有被赋值)。这时候编译器认为 i 的值没有发生改变,所以在(1)语句时从内存中取出 i 的值赋给 j 之后,这个值并没有被丢掉,而是在(2)语句时继续用这个值给 k 赋值。编译器不会生成出汇编代码重新从内存里取 i 的值,这样提高了效率。
但要注意:(1)、(2)语句之间 i 没有被用作左值才行。
再看另一个例子:
volatile inti=10;
intj = i;//(3)语句
intk = i;//(4)语句
volatile 关键字告诉编译器 i 是随时可能发生变化的,每次使用它的时候必须从内存中取出 i 的值,因而编译器生成的汇编代码会重新从 i 的地址处读取数据放在 k 中。
如果 i 是一个寄存器变量或者表示一个端口数据或者是多个线程的共享数据,就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。
int checkSystem{ union check { int i; char ch; }c; c.i = 1; return(c.ch == 1); }
若处理器是 Big_endian 的,则返回 0;若是 Little_endian 的,则返回 1。
大端模式(Big_endian) :字数据的 高字节 存储在 低地址中,而字数据的 低字节 则存放在 高地址中。
小端模式(Little_endian):字数据的 高字节 存储在 高地址中,而字数据的 低字节 则存放在 低地址中。
百度百科:
目前 Intel 的 80x86 系列芯片是唯一还在坚持使用小端的芯片,而 MIPS 和 ARM 等芯片要么采用全部大端的方式储存,要么提供选项支持在大小端之间切换。
另外,对于大小端的处理也和编译器的实现有关,在 C 语言中,默认是小端的(但在一些对于单片机的实现中却是基于大端,比如 Keil C51),Java 是平台无关的,默认是大端。在网络上传输数据普遍采用的都是大端。
union { int i; char a[2]; }*p,u; p = &u; p->a[0] = 0x39; p->a[1] = 0x38;
union 型的成员的存取都是相对于该联合体基地址的偏移量为 0 处开始的。
#include <stdio.h> int main(void) { int a[5] = {1,2,3,4,5}; int *ptr1 = (int *)(&a + 1); int *ptr2 = (int *)((int)a + 1); printf("%x,%x\n",ptr1[-1],*ptr2); return 0; }
//代码(1) structTestStruct1 { char c1; shorts; char c2; inti; }; //代码(2) structTestStruct2 { char c1; char c2; shorts; inti; };
sizeof(TestStruct1)的值为 12
sizeof(TestStruct2)的值为 8
字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被 4 整除的地址,和可以被 8 整除的地址。)无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
可以利用#pragma pack()来改变编译器的默认对齐方式:
#pragma pack(n) //n=1,2,4,8,16…
enum Color { GREEN = 1, RED, //2 BLUE, //3 GREEN_RED = 10, GREEN_BLUE //11 }ColorVal;
// 功 能: 改变缓冲区大小 // 参 数: nNewSize 缓冲区新长度 // 返回值: 缓冲区当前长度 // 说 明: 保持原信息内容不变
/************************************************************************ * Function Name : nucFindThread * Create Date : 2000/01/07 * Author/Corporation : your name/your company name * * Description : Find a proper thread in thread array. * If it’s a new then search an empty. * * Param : ThreadNo : someParam description * ThreadStatus : someParam description * * Return Code : Return Code description,eg: ERROR_Fail: not find a thread ERROR_SUCCEED: found * * Global Variable : DISP_wuiSegmentAppID * File Static Variable : naucThreadNo * Function Static Variable : None * *------------------------------------------------------------------------ * Revision History * No. Date Revised by Item Description * V0.5 2008/01/07 your name … … ************************************************************************/ static unsigned char nucFindThread(unsigned char ThreadNo,unsigned char ThreadStatus) { // TODO:... } //Blank Line
文件命名:模块名缩写 + 小写字母名字
/************************************************************************ * File Name : FN_FileName.c/ FN_FileName.h * Copyright : 2003-2008 XXXX Corporation,All Rights Reserved. * Module Name : DrawEngine/Display * * CPU : ARM7 * RTOS : Tron * * Create Date : 2008/10/01 * Author/Corporation : WhoAmI/yourcompany name * * AbstractDescription : Place some descriptionhere. * *-----------------------Revision History-------------------------------- * No Version Date Revised By Item Description * 1 V0.95 08.05.18 WhoAmI abcdefghijklm WhatUDo * ************************************************************************/ #ifndef __FN_FILENAME_H #define __FN_FILENAME_H #endif // Debug Switch Section // Include File Section // Macro Define Section // Structure Define Section // Prototype Declare Section // Global Variable Declare Section // File Static Variable Define Section // Function Define Section
标签:
原文地址:http://www.cnblogs.com/luoxu34/p/5324274.html