让指针指向初始位置c语言,初始C语言中的指针(翁凯男神MOOC)

运算符  &

●scanf("%d",&i);

●获得变量的地址,它的操作数必须是变量

● int i; printf("%x",&i);

Int i=0;

printf("%p\n",&i);

● 地址的大小是否与int相同取决于编译器

&不能取的地址

●&不能对没有地址的东西取地址

●&(a+b)

●&(a++)

●&(++a)

9dc99b1efca90d315fc24fc2be7b2864.png

4af0081b8aa26cbcbad953f032c17cad.png

int a[10];

printf("%p\n",&a);

printf("%p\n",a);

printd("%p\n",&a[0]);

指针

●就是保存地址的变量

inti;int *p=&i;

●指针指向某一个变量,指针里存放那个变量的地址

指针变量

●变量的值是内存的值

●普通变量的值是实际的值

●指针变量的值具有实际值的变量的地址

作为参数的指针

● void f(int *p);

●在被调用的时候得到了某个变量的地址;

●int i=0;f(&i);

●在函数里面可以通过这个指针访问外面的这个i

访问那个地址上的变量*

● *是一个单目运算符,用来访问指针的值所表示的地址上的变量

● 可以做右值也可以做左值

● int  k=*p;

● *p = k+1;

指针应用场景

●交换两个变量的值

void swap(int *pa.int*pb)

{int t = *pa;*pa=*pb;*pb=t;

}

●函数返回多个值,某些值就只能通过指针返回

void minmax(int a[],int len,int *max,int *min);int main(int argc, char **argv)

{int a[]={1,231,4,444,33};intmin,max;

minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);

printf("min=%d,max=%d\n",min,max);return 0;

}void minmax(int a[],int len, int *max,int *min){inti;*min=*max=a[0];for(i=0;i

}if(a[i]>*max){*max=a[i];

}

}

}

●函数返回运算的状态,结果通过指针返回

●常用的套路是让函数返回特殊的不属于有效范围内的值来表示出错:

● -1 或 0 (在文件操作会看到大量的例子)

●但是当任何数值都是有效的可能结果时,就得分开返回了

int divide(int a,int b ,int *result);int main(int argc, char **argv)

{int a=5;int b=2;intc;if(divide(a,b,&c)){

printf("%d\n%d\n%d\n",a,b,c);

}return 0;

}int divide(int a,int b,int *result)

{int ret=1;if(b==0)ret=0;else{*result=a/b;

}returnret;

}

●后续的语言(C++ Java)采用了异常机制来解决这个问题

指针最常见的错误

●定义了指针变量,还没有指向任何变量,就开始使用指针

传入函数的数组成了什么?

●函数参数表中的数组实际上是指针

●size of (a)==size of (int*)

●但是可以用 数组的运算符[]进行运算

数组参数

●以下四种函数原型是等价的

● 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

指针是const(指针指向那个变量,这个事实不能被改变)

●表示一旦得到了某个变量的地址,不能再指向其他变量

int *const q =&i; //q是const

*q = 26; //OK

q++; //ERROR

所指的是const

●表示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)

const int *p = &i;*p=26; //ERROR! (*p)是const

i=26; //OK

p=&j; //OK

转换

●总是可以把一个非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,5};

●数组变量已经是const的指针了,这里的const表明数组的每个单元都是const int

●所以必须通过初始化进行赋值

指针运算

●给一个指针加1表示要让指针指向下一个变量

int a[10];int *p=a;

*(p+1)--->a[1]

●如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义

指针计算

●给指针加,减一个整数(+,+=,-,-=)

●递增递减(++/--)

●两个指针相减(地址的差除以sizeof( 类型))

*p++

●取出p所指的那个数据来,完事之后顺便把p移动到下一个位置去

● *的优先级虽然高,但是没有++高

●常用于数组类的连续空间操作

●在某些CPU上,这可以直接被翻译成一条汇编指令

char ac[] = {0,1,2,3,4,5,-1}; //-1不是有效数字

char *p=acwhile(*p != -1){

printf("%d\n",*p++);

}

遍历数组ac

0地址

●当然你的内存中有0地址,但是0地址通常是个不能随便碰的地址

●所以你的指针不应该具有0值

●因此可以用0地址来表示特殊的事情:

●返回的指针是无效的

●指针没有被真正初始化(先初始化为0)

●NULL是一个预定定义的符号,表示0地址

●有的编译器不愿意你用0来表示0地址

指针的类型

●无论指向什么类型,所有的指针的大小都是一样的,因为都是地址

●但是指向不同类型的指针是不能直接互相赋值的

●这是为了避免用错指针

指针的类型转换

●void* 表示不知道指向什么东西的指针

●指针类型亦可以转换类型

●int *p = &i;   void*q = (void*)p;

●这并没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量

●我不再当你是int啦,我认为你就是一个void!

用指针来做什么

●需要传入较大的数据时用作参数

●传入数组后对数组做操作

●函数返回不止一个结果

●需要用函数修改不止一个变量

●动态申请内存时

malloc

●#include

●向malloc申请的空间的大小都是以字节为单位的

●返回的结果是void*,需要类型为自己需要的类型

●(int*)malloc(n*sizeof(int))

#include #include

int main(void)

{intnumber;int *a;

printf("输入数量");

scanf("%d",&number);

a=(int*)malloc(number*sizeof(int));for (i=0;i

a[i]=i*i;

}

free(a);

return 0;

}

没空间了?

●如果申请失败则返回0,或者叫做NULL

void *p=0;int cnt=0;while((p=malloc(1024*1024*1024))){

cnt++;free(p)

printf("分配了%d00MB的空间\n",cnt);

free()

●把申请得来的空间还给系统

●申请过来的空间,最终都要还

●混出来的,迟早都要还的

●只能还申请的空间的首地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值