1 指针
声明一个指向int类型变量的指针:
int *pointer = NULL;
声明指针时一定要初始化!
int number = 10;
int *pointer = &number;
可以和其它变量一起声明:
int *p, q; //声明了指针变量p和整型变量q
使用间接运算符*可以访问指针所指的变量值。这个运算符也称为取消引用运算符:
int number = 3;
int *pointer = &number; //pointer变量含有number变量的地址
int result = 0;
result = *pointer + 5; //8
使用指针:1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
int num1=0L, num2=0L, *p=NULL; //初始化指针变量p
p = &num1; //p指向num1
num2 = ++*p; //p和num2都是1
p = &num2; //p指向num2
num2 += *p; //num2等于2,所以p指向的值也是2
printf("num1=%d, num2=%d, pvalue=%d.", num1, num2, *p); //1,2,2
*p = 4; //直接赋值
printf("num2=%d pvalue=%d.", num2, *p); //*p等于num2等于4
return 0;
}
以上可以看出p可以指向多个变量,并改变它们的值,只要它们的变量类型相同。
*p++ //一元运算符从右向左计算,所以是先递增地址,再取消引用得到值,与scanf()配合使用:
1 |
|
指向常量的指针:1
2
3
4
5
6
7
8
9
int main()
{
int value = 999;
const long *p = &value; //声明为不动值
*p = 888; //*p是不允许改变的,但可以改变p指向的地址。如long num=888;p=#
return 0;
}
常量指针:1
2
3
4
5
6
7
8
9
10
int main()
{
int value = 999;
int *const p = &value;
p = &value; //p是常量,不允许改变。但可以*p=888来改变常量的值。
printf("%d", *p);
return 0;
}
结合以上两个:
const int *const p = NULL; //这时候p完全不能改变
2 数组和指针
char multi[] = "my string";
char *p = &multi[0];
printf("%p", p);
p = multi;
printf("%p", 0);//和第二行一样的结果
3 多维数组
1 |
|
上面有
**(board+1)=4;
**board+16=A;
*(*board+1)=2; //*board==&board[0][0]
4 内存的使用
4.1 动态内存分配:malloc()
int *p = (int *)malloc(100);
100是malloc()的参数,表明要申请的内存大小,返回第一个字节的地址,所以用int *来修饰malloc()表明要把这100B保存为int型,那么能存25个int值。malloc()在<stdlib.h>中。
4.2 找质数
1 |
|
4.3 calloc()
int *p = (int *)calloc(100, sizeof(int));
与malloc()类似,只是申请成功后会用0初始化所分配的空间,两个参数都是size_t类型。
4.4 释放动态分配的内存
当动态分配了一些内存时,没有保留对它们的引用,就会出现内存泄漏,此时无法释放内存。这通常发生在循环内部,由于没有释放不再需要的内存,程序会使用更多的内存,最终占用所有内存。
使用free(p);释放内存。
4.5 重新分配内存
relloc()可以征用前面通过malloc() or calloc() or relloc()分配的内存。
relloc(p, count*sizeof(int)); //第一个参数是以前申请的内存首地址,第二个参数是需要的内存大小,很明显第二个参数要小于以前申请的内存大小。
5 使用指针处理字符串
1 |
|
地址也可以减1
2
3
4
5
6
7
8
9
int main(void)
{
long long a=1LL,b=2223LL;
printf("%p %p\n",&a, &b);
printf("%d",(int)&a-(int)&b); //8
return 0;
}
1 |
|
gets()存储换行符,并加上终止符’\0’;fgets()不存储换行符。