指针理解:
指针使用的两种场景:1.传递、2.偏移。如果不是这两种场景,就不要用指针。
指针是专门用来存放地址的变量。
指针的内容就是地址。在win32程序中,所有地址都是4个字节的。所以所有类型的指针变量都占4个字节。
指针就是一个变量,指针本身也存在内存中。指针也有自己的地址。
一级指针的使用:传递
在子函数中只要拿到i的地址。
#define OUT
void change(OUT int* p){ //子函数中定义了一个指针类型的变量p。为其分配了4个字节。
*p=5; //通过间接访问i。
}
void main(){
int i=3;
change(&i); //把i的地址传递过去。
}
一级指针的使用:偏移(即,一维数组与指针的关系)
void fun(
int *p){
//定义指针p.通过值传递:p=&a[0]。等价于 void fun(int a[])
//void fun(
int a[]){
//数组弱化为指针。
int i;
for(i=0;i<5;i++){
printf("%d\n",
p[i]);
// printf("%d\n",
*(p+i));
//*(p+i)就是p[i]
// printf("%d\n",
a
[i]);
// printf("%d\n",
*(a+i));
//*(a+i)就是a[i]
}
}
void main(){
int a[3]={1,2,3};
fun(
&a[0]);
// fun(
a);
}
二维数组的传递、偏移
void total(
int a[][4],int n){
//二维数组传递的时候弱化为一维数组指针。第二维的长度一定要写上。
//void total(
int (*p)[4],int n){
//二维数组传递的时候弱化为一维数组指针。
int i,j,sum;
for(i=0;i<n;i++){
sum=0;
for(j=0;j<sizeof(
*(a+0))/sizeof(int);j++){
//*(a+0)就是a[0],a[0]是一个数组指针
// for(j=0;i<sizeof(
*p)/sizeof(int);i++){
sum+=
a[i][j];
// sum+=
*(*(a+i)+j);
//指针写法。a+i是数组指针,指向第i个数组。*(a+i)=a[i]
}
}
}
void main(){
int a[3][4]={1,3,5,6,7,9,11,13,15,17,19,21,23};
int b[4]={17,19,21,23};
total(
a,3);
}
总结
-------------------------------------------------------------------------
#include <stdio.h>
int main(){
char *str=NULL;
printf("%c\n",str); //输出空。
printf("%d\n",*str); //这一行会报错。NULL的位置是不能获取值的,会告诉你非法访问内存。
int b=2;
int *a=&b; //a指向b,a的值为b的地址。*a就是b。
printf("%d\n",a);
printf("%d\n",*a);
return 0;
}
指针变量作为函数参数
指向数组元素的指针
int a[6];
int *p;
方法一:p=&a[0];
方法二:p=a;
通过指针引用数组元素
如果指针p指向数组中的某个元素,那么p+1指向该数组的下一个元素。
例子:
#include <stdio.h>
int main() {
int a[6]={0};
*a=1;
//*a表示a[0]的值
printf("a[0]=%d\n",a[0]);
*(a+2)=2;
//*(a+2)表示a[2]的值
printf("a[2]=%d\n",a[2]);
return 0;
}
例子:
#include <stdio.h>
int main() {
int a[6]={0};
int *p=NULL;
p=a;
*p++=0;
//等价于:*(p++)=0; 等价于:*p=0;p++;
*p=1;
printf("a[0]=%d\n",a[0]);
printf("a[1]=%d\n",a[1]);
return 0;
}
结果:
a[0]=0
a[1]=1
指针型函数
函数指针变量
int (*p)();
野指针
野指针是指向被释放的活着访问受限的垃圾内存的指针。
野指针是很危险的,if无法判断一个指针式正常指针还是野指针。
养成良好的变成习惯是避免野指针的唯一方法。
main函数中的指针数组
main函数可以带参数,这个参数可以认为是main函数的形参。
C语言规定,main函数的参数只能有2个,并且,第一个形参必须是整形变量,第二个形参必须是指向字符串的指针数组。
因此,main函数可以定义为: void main(int argc,char *argv[])
main函数的参数值是从命令行获得的,例如:test.exe a b c