一、在多重循环中,应将最忙的循环放在最内层,以减少CPU切入循环层的次数。
二、Linux内核版本号由3部分组成:主版本号、次版本号和次次版本号。例如,2.4.20-8,2是主版本号,4是次版本号,20是次次版本号,最后的数字是被修订的次数。
三、路径的表示方法有两种:一种是从根目录开始的,称为绝对路径;另一种是从当前目录开始的,称为相对路径。
四、字符常量存储的是它的ASCII码(用一个字节)
字符变量:字符型变量实质上是一个8位的数值,其值范围为-2^7~2^7-1,即,-128~127
字符串常量:由一对双引号括起来的字符序列,字符串常量在内存中存储时,每个字符占用一个字节的内存空间,系统自动在字符串尾部加上一个字符'/0'。在c语言中,字符串使用字符数组来存储的。
五、一种交换值的方法 条件 int a=1,b=2
方法 a=a+b;
b=a-b;
a=a-b;
六、在使用gcc编译程序时,编译过程可以分为4个阶段
(1)预处理:(Pre-Processing)
(2)编译:(Compling0)
(3)汇编:(Assembling)
(4)链接:(Lingking)
预处理阶段,输入的是C语言的源文件,通常为*.c或*.C,但它们一般带有*.h之类的头文件。这个阶段主要处理源文件中的#ifdef、#include和#define预处理命令。该阶段会生成一个中间文件*.i,但实际工作中一般不用专门生成这种文件,若必须要生成这种文件,可以使用以下命令:
gcc -E test.c -o test.i
在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*s。这个阶段对应的gcc命令如下所示:
gcc -S test.i -o test.s
在汇编阶段,将输入的汇编文件*.s转换成二进制机器代码*.o。这个阶段对应的gcc命令如下所示:
gcc -c test.s -o test.o
最后,在链接阶段将输入的二进制代码文件*.o(与其他的机器代码文件和库文件)汇集成一个可执行的二进制代码文件。这一步,可以使用下面的示例命令完成:
gcc test.o -o test
七、C程序中包含头文件有两种方法:
(1)#include <myinc.h>
编译器gcc在系统预设包含文件目录中查找相应的头文件myinc.h,对于系统提供的头文件,通常用<>
(2)#include "myinc.h"
编译器gcc首先在当前目录中查找头文件,如果当前目录没有找到需要的头文件,就到指定的目录中去找
在实际开发中,对于自己编写的头文件,通常放在与源程序相同的目录中,采用“”
八、关于“库”
库是事先已经编写好的代码,经过编译后可以直接调用的文件。也可以属于自己的库文件,以方便自己使用或提供给他人使用。库体现了软件工程中软件重用的思想。库分为两种:静态库和动态库。
九、浮点数比较问题
不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”之类的形式
错:if(x == 0.0)
正确:if((x>=-0.00001) && (x<=0.00001))
十、函数
在定义函数时,函数名后面括号中的变量称为形式参数,如变量a,b,简称形参;在调用函数时,函数后面括号中的参数称为实际参数。实参可以是变量或者是常量表达式。
形参在定义时不分配内存单元,只有在被调用时,才被分配内存单元。调用结束后,形参所占的单元即被收回。(值传递)
如果函数的返回类型与return语句返回的值类型不一致,以函数的返回类型为准。对于数值类型将会自动进行类型转换。
函数体内的变量随着函数被调用而分配内存空间,函数调用结束存储函数体为定义的内存空间即被收回。函数可以返回一个指针但不可以返回一个数组。
若调用语句在函数定义之前,则应该对函数先进行声明。若调用语句在函数定义之后,则不必对函数进行声明。
要保证递归调用到一定条件将不会继续递归下去而是返回一个值。这个条件是程序中给出的,这是递归调用函数设计时必须注意的地方。
动态变量是指在程序运行过程中根据需要动态分配内存空间的变量,主要有:函数的形参、函数内定义非static变量
静态变量是指在程序运行过程分配固定的存储空间的变量,函数调用结束后并不会销毁,存储在静态存储区的内存里。程序运行结束后才会释放该静态内存。函数内定义的static变量、全局变量。
extern对全局变量进行声明,说明变量在别处定义了。
全局变量是在所有函数的外部定义的,它的作用域从变量定义处开始到本程序文件结束。编译时系统为全局变量在静态存储域分配内存空间。
十一、数组
在所有函数外定义的数组的所有元素将被自动赋予初值0,在函数内部定义的函数,系统不会为其进行初始化,在使用数组元素前必须对元素进行初始化。
二维数组赋值:(1)将所有数据写在一个大括号内,依次赋值;(2)分行赋值;(3)部分赋值;(4)如果对全部元素都赋值,则定义数组时第一维数可以省略,但第二维的维数必须指定。array[][4]={1,2,3,4,5,6,7,8,9,10,11,12}
十二、指针
指针数组形式 类型名 *数组名[数组长度];
1、int *p[5];指针数组
2、int (*p)[5];p是一个指针,指向含有5个元素的一维数组。p也只能指向一个包含5个元素的一维数组,p就是该一位数组的首地址。
指针作为函数的参数;返回指针的函数;
3、指向函数的指针,(函数指针)一个函数的函数名是一个指针,它指向函数的代码。函数的调用可以通过函数名来调用也可以通过指向函数的指针来调用。例如,int (*p)(int i,int j);函数赋值只赋函数名。即,p=fun;
4、函数指针做形参
5、返回函数指针的函数
十三、指向字符串的指针
void copy_string(char *src, char *dst)
{
for(;*src != '/0';)
*dst++=*src++;
*dst='/0';
}
注意:数组char a[20],a是指向数组的第一个元素的指针,它的值不可以被改变,它在运行过程中始终指向数组的第一个元素。而在函数定义中,如void copy_string(char src[], char dst[]),src也是一个指针,但它的值是可以改变的,也就是说,它可以指向其他字符变量。
static的用途如下:
(1)限制变量的作用域
(2)设置变量的存储域
static全局变量与普通全局变量:都是静态存储方式,存储在内存的静态存储区。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件中有效。
程序的普通局部变量存于堆栈中,全局变量、static局部变量都存于静态存储区中。
十四、调试器gdb
next与step命令的区别是:如果遇到函数调用,next(不进入函数体)会把该函数调用当作一条语句来执行,当再次输入next会执行函数调用后的语句;而step(进入函数体)则会跟踪进入函数,一次一条地执行函数内的代码,知道函数内的代码执行完,才执行函数调用后的语句。nexti和stepi用于执行一条机器指令。
十五、两个指针赋值时,这两个指针所指向的数据的类型必须一致。
sizeof输出的是字符串包括最后一个结束字符'/0'的总长度。strlen则不包括结束字符'/0'的长度。
char *p1, sizeof(p1)=4.求得的是指针变量p1的长度,我么知道一个指针变量存放的是一个地址,而32位机器的一个地址都是32位,即4个字节.
int (*s[10])(int)含义:定义了一个含有10个函数指针的数组,数组的长度是10,数组元素的类型是指向函数的指针。
面试题举例,假设你知道一个数组的数组名,如何确定这个数则的长度?
int lenth = sizeof(arryname) / sizeof(arrayname[0]);(注意:数组做形式参数时,不能这样用,因为值传递地址)
例子:int array[100]; array是指向array[0]的指针 &array是指向长度为100的数组的指针
十六、预处理命令
预处理命令并不是c语言的一部分,因此每条编译预处理命令不需要以分号来结束。
宏的作用范围是从宏定义开始到本源程序文件结束为止。也可以使用#undef来提前终止作用范围。宏允许嵌套定义,如:#define MIN 128
#define MAX MIN*2
规范写法: #define MUL(x,y) (x)*(y)
文件包含 #include <文件名> 或 #inlcude "文件名" 把指定的文件的全部内容包括进来,插入到命令行所在位置,取代原来的命令行。由当前源文件和指定文件组成一个文件,一起进行编译。
一个大的程序往往被分为多个模块,由多个程序员编写。公用的信息,如常量定义,函数声明,可以到哪度放在一个文件中,在其他文件的开头使用#include命令包含进来,这样可以避免每个文件头部都去写那些公用量,节省时间和出错的可能。
<>尖括号只在缺省的目录里找指定文件,缺省目录是用户设置的编程环境决定的。 ""则先在源程序文件所在的当前目录里查找指定文件,如果没有找到再到缺省目录里找。
条件编译
(1)ifndef (2)ifdef (3)if 表达式
程序段; 程序段; 程序段;
endif endif endif
if...no...def if...def 表达式成立
举例:分别用函数和带参数的宏,实现从3个数中找出最大数?
#include <stdio.h>
#define MAX(a,b) a>b?a:b
int max(int a,int b,int c)
{
return (a>b?a:b)>c?(a>b?a:b):c;
}
int main(void)
{
int a,b,c,m;
printf("Input three integers:");
scanf("%d %d %d",&a,&b,&c);
#ifdef MAX(a,b)
m=MAX(MAX(a,b),c);
#else
m=max(a,b,c);
#endif
printf("%d/n",m);
return 0;
}
十七、结构体和共用体
声明结构体时系统并不为它分配内存空间,只有定义了结构体类型的变量,系统才为该变量分配存储空间。也可以一边声明一边定义结构体变量。
4字节对齐规则:分配的内存是4的倍数,不够的会自动补齐。
一个结构体指针指向结构体变量,结构体指针所保存的值是它所执行结构体变量所占内存的首地址。引用方式为: 指针->结构体成员
共用体把不同的数据类型的变量存放在同一块内存中,共用体中的变量共享同一块内存。同一块内存可以用来存放不同的数据,但在同一时刻只能在其中存放一个成员变量,共用体中起作用的成员是最后一次存入的数据。
typedef是为已存在的数据类型声明一个别名。
位域:c语言允许在一个结构体中以位为单位来使用内存,这种以为为单位的成员称为位域位段。