定义
1)指针就是地址,地址就是指针;
2)指针变量就是存放内存单元地址的变量;
3)指针本质是一个操作受限的非负整数,操作受限为指针不象普通的非负整数一样进行运算;指针不能加,乘,除,只能在某些情况下进行相减;
c指针代码示例
# include <stdio.h> int main(void) { int i = 1; int j; int * p= &i; //此处等价于int *p; p=&i;定义了一个指针变量p,p只是一个变更的名字,int * 表示变量p只能存储int型的指针数据 j = *p; //此处,等价于j = i,因此*p也等价于*p=i; printf("i=%d, j=%d, p=%d\n", i,j,*p); }
# include <stdio.h>
void f(int * p)//此处是定义了一个名叫p的形参,且p的类型为int *
{
*p = 100;
}
int main(void)
{
int i = 9;
f(&i);
printf("i=%d\n", i);
return 0;
}
一维数组与指针的关系
1)一维数组名是个指针常量;
2)存放的是第一个元素的地址,且该量不能被改变
3)下标与指针的关系:a[i] 等价于 *(a+i)
4)c中数组在内存中的存放物理地址是连续的;
一维数组代码示例:
# include <stdio.h> int main(void) { int a[5] = {1,2,3,4,5}; *(3+a) = 40; 4[a] = 50; printf("%d,%d\n", a[3],a[4]); printf("%p\n", a+1);//此处为输出a[1]的地址,p%是以16进制输出 printf("%p\n", a+2); printf("%p\n", a+3); printf("%d\n", *a+3); //此处*a+3等价于a[0]+3 }
[pikaqiu@localhost c]$ gcc -o test1 test.c [pikaqiu@localhost c]$ ./test1 40,50 0x7fff13f3ef54 0x7fff13f3ef58 0x7fff13f3ef5c 4
无论指针变量指向哪里,指针变量本身都只占4个字节;
malloc函数动态分配内存的时候,只会返回所请求空间(如请求20个字节)的第一个字节的地址;
静态定义的数组除非程序终止,否则会一直占用内存,而动态分配的数组可以在程序执行过程中随机释放;
# include <stdio.h> # include <malloc.h> int main(void) { int a[5] = {1,2,3,4,5}; int len; printf("请输入你需要分配的数组的长度:len = "); scanf("%d", &len); //动态定义数组 //malloc函数返回是动所请求空间(如请求20个字节)的第一个字节的地址(干地址) //所以malloc函数前面必须将其强制转换为具体的数据类型,才能通过*(a+n)的方式找到后面的元素 //sizeof返回的是int数据所占的字节数 int * pArr = (int *)malloc(sizeof(int) * len); int i; for (i=0; i<len; ++i) scanf("%d",&pArr[i] ); for (i=0; i<len; ++i) printf("%d\n", *(pArr+i)); free(pArr); }
[pikaqiu@bogon c]$ gcc -o test test.c [pikaqiu@bogon c]$ test [pikaqiu@bogon c]$ ./test 请输入你需要分配的数组的长度:len = 5 1 2 3 4 5 1 2 3 4 5
malloc函数分配的内存必须手动用free释放,如是在某个函数内部分配的内存空间,该函数执行完毕后,该内存依然存在,但当整个程序执行完毕后,该内存会被回收;
#include <stdio.h> #include <malloc.h> //跨函数使用内存示例 int f(int **q) { *q = (int *)malloc(4); } int main(void) { int *p; f(&p); }
malloc动态分配内存分配失败时会返回NULL,因此使用该函数分配内存时,一定要判断返回值是否为空;