结论:
当指针p指向一个同类型的数组的元素时:p+1将指向当前元素的下一个元素;p-1将指向当前元素的上一个元素。
如:int a[] = {1,2,3,4} a[1] = *(a+1) = *(p+1)
指针之间只支持减法运算,且必须参与运算的指针类型必须相同
p1 – p2; ( (unsigned int)p1 - (unsigned int)p2) / sizeof(type);
注意:
只有当两个指针指向同一个数组中的元素时,指针相减才有意义,其意义为指针所指元素的下标差,当两个指针指向的元素不在同一个数组中时,结果未定义
(数组)下标VS 指针
从理论上而言,当指针以固定增量在数组中移动时,其效率高于下标产生的代码.当指针增量为1且硬件具有硬件增量模型时,表现更佳
现代编译器的生成代码优化率已大大提高,在固定增量时,下标形式的效率已经和指针形式相当;但从可读性和代码维护的角度来看,下标形式更优。
C语言中,数组作为函数参数时,编译器将
其编译成对应的指针
void f(int a[]); = void f(int* a);
void f(int a[5]); = void f(int* a);
结论:
一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标示数组的大小。
malloc分配的内存没有被初始化,calloc分配的初始化了
char *a = "123" char *b = "1234"
if(strlen(a) > strlen(b))
if(stren(a) < strlen(b)) //strlen返回值为无符号整数,相减不可能小于0
C语言中通过typedef为数组类型重命名
typedef type(name)[size];
数组类型:
typedef int(AINT5)[5];
typedef float(AFLOAT10)[10];
数组定义:
AINT5 iArray;
AFLOAT10 fArray;
数组名是数组首元素的起始地址,但并不是数组的起始地址
通过将取地址符&作用于数组名可以得到数组的起始地址
main函数可以理解为操作系统调用的函数
在执行程序的时候可以向main函数传递参数
int main()
int main(int argc)
int main(int argc, char *argv[])
int main(int argc, char *argv[], char *env[])
argc – 命令行参数个数
argv – 命令行参数数组
env – 环境变量数组
为什么需要指向指针的指针?
指针在本质上也是变量,对于指针也同样存在传值调用与传址调用
C语言中只会以值拷贝的方式传递参数
当向函数传递数组时,将数组名看做常量指针传数组首元素地址。
C语言以高效为最初设计目标,在函数传递的时候如果拷贝整个数组执行效率将大大下降。
二维数组参数中第一维的参数可以省略。为了提供正确的指针运算,必须提供除第一维之外的所有维长度
void f(int a[5]); void f(int a[]); void f(int* a);
void g(int a[3][3]); = void g(int a[][3]); = void g(int (*a)[3]);
指针数组做参数:int* a[5] == 指针的指针:int** a
回调函数是利用函数指针实现的一种调用机制
回调机制原理
调用者不知道具体事件发生的时候需要调用的具体函数,被调函数不知道何时被调用,只知道被调用后需要完成的任务。当具体事件发生时,调用者通过函数指针调用具体函数,回调机制的将调用者和被调函数分开,两者互不依赖
malloc实际分配的内存可能会比请求的稍微多一点,但是不能依赖于编译器的这个行为
• 当请求的动态内存无法满足时malloc返回NULL
• 当free的参数为NULL时,free函数直接返回
char *p = (char *)malloc(0); 可以返回一个有效地址没错,可是为什么这个可以正常使用? 它哪来的内存呢?? 我在linux下 测试居然能正常使用这个指针,而且是可以free的 这涉及到malloc内的内存分配算法。通常malloc有个最小单元分配,也就是申请1个字节,可能要分配n字节给应用程序
|