Scanf
如果能够将取得的变量的地址传递给一个函数,能否通过这个地址在那个函数内访问这个变量
scanf("%d",&i);
指针
就是保存地址的变量
int i;
int* p = &i;
int* p,q;
int *p,q;
变量的值是内存的地址
普通变量的值是实际的值
指针变量的值是具有实际值的变量的地址
int *p = i; // 假设 i 的变量地址值是 0x2001,这句代码就是将 i 的地址值 0x2001 赋值给 p ; 不管 i 里面是什么内容 p 的内容只会是 0x2001
作为参数的指针
void f(int * p);
再别调用的时候得到某个变量的地址:
int i = 0;f(&i);
在函数里面可以通过这个指针访问我们的这个 i ;
传入地址
为什么
int i;scanf("%d",i);编译没有报错?在大多数C/C++编译器中应该是会报错的。这是因为
scanf函数期望其第二个及后续参数是指针类型,用于接收输入的数据。i是一个整数变量,而不是一个指向整数的指针。正确代码
int i;scanf("%d", &i);
指针最常见的错误
定义了指针变量,还没有指向然后变量,就开始使用指针
int *p ;int i = 18;*p = 12;// 错误写法i = 18;*p = 12;// 12会开辟另外的空间比如 0xaab, *p 指向 0xaab,如果刚好 0xaab 不能写,程序就会报错
指针和数组
数组参数
四种函数原型等价
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 = ...
指针是 const
表示一旦得到某个变量的地址,不能再指向其他变量
int * const q = &i; // q 是 const
*q = 26; // ok
q++; // ERROR
转换
总是可以把一个非 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
int sum(cosnt int a[] , int length);