以下均为个人看了《C和指针》Reek著 人民邮电出版社后将之前不清楚或觉得需要强调的摘抄的:
预处理指令:
如下均为预处理指令:
#include <stdio.h>
#include <string.h>
#define MAX_COLS 20
预处理指令(preprocessor directives)由预处理器(preprocessor)解释,预处理器读入源代码,根据预处理指令对其进行修改,然后把修改过的源代码递交给编译器。
环境
翻译环境:源代码被转换为可执行的机器指令
执行环境:用于实际执行代码
例如:交叉编译器,在一台机器上运行,但它所产生的可执行代码运行于不同类型的机器上。
字符串常量:
被双引号括起来的一串字符
eg:”Hello” 在内存中占据6个字节的空间,(结尾有一个NULL)
—————–常用printf格式代码——————–
%d 十进制
%o 八进制
%x 十六进制 (十六进制中,可以使用字母ABCDEF或abcdef)
—————–常用scanf格式代码——————–
%d 读取一整型值
%f 读取一浮点数
%c 读取一字符
%s 读取一字符串
注:前三种因为读取标量值,所以变量参数前加“&”eg
scanf("%d",&columns[num]);
—-类型————————–最小范围——-
unsigned char —————- 0~255
short int —————— -32767~32767
unsigned short int———- 0~65535
int ————————— -32767~32767
浮点数默认情况:double类型,后面跟一个L或l:long double / F或f:float类型
int* a, b, c; //b c为int!
int *a, *b, *c;
int a, *pi;
pi = &a; //pi的值为内存中某个特定位置的地址(a的存储地址),*操作符使机器指向那个位置
NULL指针:要使一个指针变量为NULL,可以给他赋一个零值。
可以把字符串常量赋值给一个“指向字符的指针”,不能将其赋值给一个字符数组,因为字符串常量的直接值是一个指针!:
char *message = "hello";
等效于:
char *message;
message = "hello";
函数如果不显式地声明返回值类型,默认返回整型。
const:
int const a;
等效于:
const int a;
int const *pci; //不能修改它所指向的值
int * const cpi; //指针是常量,它的值不能修改,但能修改它所指向的整型的值
static:
static int c(int d)
{
...
}
可以防止它被其它源文件调用
extern:
为一个标识符指定external链接属性,可以访问在其他位置定义的这个实体
变量的存储类型:
在代码块之外声明的变量:存储于静态内存中,不属于堆栈的内存,静态变量。
在代码块内部声明的变量:缺省存储类型是自动的,存储于堆栈中,自动变量。
可以通过static,将存储类型从自动变为静态。
具有静态存储类型的变量在整个程序执行过程中一直存在,而不仅仅在声明它的代码块的执行时存在。但,注意:修改变量的存储类型并不表示修改该变量的作用域,仍只能在该代码块内部按名字访问。
局部变量由函数内部使用,不能被其它函数通过名字引用。缺省情况下存储类型为自动:一,当这些变量需要时才为他们分配存储,可以减少内存的总需求量;二,在堆栈上为它们分配存储可以有效地实现递归。
static关键字总结:
当它用于函数定义时,或用于代码块之外的变量声明时:
只能在声明他们的源文件中访问
当它用于代码块内部的变量声明时:
如上(变量的存储类型中)所述,用这种方式声明的变量在程序执行之前创建,在程序的整个执行期间一直存在,而不是:每次在代码块开始执行时创建,在代码块执行完毕后销毁。
示例:
int a = 5; //链接属性为默认的:external
extern int b; //b的定义可以在此or其他地方
static int c; //static修改链接属性为internal
//以上三个存储类型为静态,不存储于堆栈中,在程序执行之前创建并一直保持他们的值,直到程序结束。
int d(int e)
{
...
{
int a;
...
}//a的作用域本来是全程序,但该{}内有同名的变量,所以在该{}内,a指的是这{}里定义的
//a,{}结束之后a指的是开头定义的a
...
}
例子,在一组字符串中查找:
int
find_char(char **strings, char value) //strings: 指向字符串的指针的指针
{
char *string;
while((string = *strings++) != NULL) //指针数组以NULL指针结束
{
while(*string != '\0') //string:指向字符串的指针,字符串以'\0'结尾
{
if(*string++ == value)
return 1;
}
}
return 0;
}
指针运算:
当一个指针和一个整数量执行算术运算时,整数在执行加法运算前始终会根据合适的大小进行调整:
合适的大小:指针所指向类型的大小
调整:整数值和“合适的大小”相乘
两个指针相减:结果类型是一个有符号整数类型,值为两个指针在内存中的距离(以数组元素的长度为单位,而不是字节! &p[j]-&p[i] = j - i )
追踪递归函数:
变量创建于运行时堆栈上的,以前调用的函数变量仍保留在堆栈上,但他们被新函数的变量所掩盖,因此不能被访问。
对于下面这个求阶乘问题:
factorial(n) = 1 (n = 0)
n * factorial(n-1) (n > 0)
如果用 递归函数 来做,会在运行时有些开销:参数必须压到堆栈中,为局部变量分配内存空间,寄存器的值必须保存。当递归函数的每次调用返回时,上述这些操作必须还原,恢复成原来的样子。:
long factorial(int n)
{
if( n == 0)
return 1;
else
return n * factorial(n - 1);
}
所以不如用 迭代 来算阶乘:
long factorial(int n)
{
int result = 1;
while( n > 1)
{
result *= n;
n -= 1;
}
return result;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。