指针
- int* p,q;与int *p,q;相等,“ * ”是一对一的,空格位置不影响。
void f(int *p);//被调用时得到了某个变量的地址
int i=0;f(&i);//在函数里面可以通过这个指针访问外面这个i
- “*” 是一个单目运算符, 用来访问指针的值所表示的地址上的变量,可以做右值也可以做左值。
- int k = *p;*p=k+1;
应用场景
1.交换两个变量的值
void swap(int *pa,int *pb)
{
int t=*pa;
*pa=*pb;
*pb=t;
}
2.函数返回多个值,某些值只能通过指针返回
返回的参数实际上是需要保存带回的结果的变量
- 函数返回运算的状态, 结果通过指针返回
- 常用的套路是让函数返回特殊的不属于有效范围内的值来表示出错:-1 或0 ( 在文件操作会看到大量的例子)
- 但是当任何数值都是有效的可能结果时, 就得分开返回了
- 地址变量没被赋值前(未得到实际变量地址)不能通过其访问任何数据、变量。
数组参数
以下四种函数原型是等价的
int sum(int *ar, int n);
int sum(int * , int);
int sum(int ar[], int n);
int sum(int [ ] , int);
数组变量是特殊的指针
- 数组变量本身表达地址, 所以
- int a[10]; int*p=a; / / 无需用&取地址
- 但是数组的单元表达的是变量, 需要用& 取地址
- a==&a[0]
- “[ ]” 运算符可以对数组做, 也可以对指针做:
- p[0]–>a[0]
- *运算符可以对指针做, 也可以对数组做:
- *a=25
- 数组变量是const 的指针, 所以不能被赋值
- int a[ ] < = = > int * const a
int * const q:指针是const,一旦得到某变量地址不再指向其他变量。
const int * p(int const * p):所指是const,不能对所指的值进行操作(只读),并不能使所指变量成为const,但该指针可以指向新的地址。
判断标志是const在 * 的前面还是后面
转换
总是可以把一个非const 的值转换成const 的
void f(const int* x) ;
int a=15 ;
f(&a);//ok
const int b = a ;f(&b);//ok
b = a + 1 ; // Error!
- 当要传递的参数的类型比地址大的以候, 这是常用的手段: 既能用比较少的字节数传递值一口参数, 又能避免函数对外面的变量的修改。
- const数组必须通过初始化进行赋值(const int a[]={1,2,3,4,};),把数组传入函数时传递的是地址,可以修改数组的值,为保护数组可设置const数组。
指针的类型 - 无论指向什么类型, 所有的指针的大小都是一样的, 因为都是地址
- 但是指向不同类型的指针是不能直接互相赋值的
- 这是为了避免用错指针
指针的类型转换 - void* 表示不知道指向什么东西的指针
- 计算时与char * 相同( 但不相通)
- 指针也可以转换类型
int * p = &i; void *q = (void * )p, - 这并没有改变p 所指的变量的类型, 而是让后人用不同的眼光通过p 看它所指的变量
使用void*来表示指针的类型,从而忽略指针类型不同带来的作用
int a[] = {5, 15, 34, 54, 14, 2, 52, 72}; int *p = &a[5]; 则:
p[-2]的值是54
用指针来做什么
- 需要传入较大的数据时用作参数
- 传入数组后对数组做操作
- 函数返回不止一个结果
- 需要用函数来修改不止一个变量
- 动态申请的内存
动态内存分配
malloc函数
#include <stdlib.h>
void* malloc(size_t size);
- 向malloc申请的空间的大小是以字节为单位的
- 返回的结果是void * , 需要类型转换为自己需要的类型
(int*)malloc(n*sizeof(int))
- 如果申请失败则返回0 , 或者叫做NULL
***free函数***跟malloc对应
#include<stdio.h>
#include<stdlib.h>
int main()
{
void *p;
int cnt=0;
while(p=(malloc(100*1024*1024))){
cnt++;
}
printf("分配了%d00MB的空间",cnt);
free(p);
return 0;
}
相邻两次malloc得到的空间一般不是连续的,malloc从空闲内存列表中寻找合适的空间进行分配。
得到的空间的实际大小一般大于你要求的大小,malloc以最小分配的空间作为基本单位分配空间。
malloc零长度会得到一个最小分配的空间。
对于以下代码段,正确的说法是:
char *p;
while (1)
{
p = malloc(1);
*p = 0;
}
A. 最终程序会因为没有没有空间了而退出
B. 最终程序会因为向0地址写入而退出
C. 程序会一直运行下去
D. 程序不能被编译
malloc在分配内存失败时并不会终止程序,而是返回NULL指针。而第5行代码试图向NULL指针位置写入数据,这会引起程序终止(通常操作系统会因为“段错误”而终止程序)