指针 部分

关于指针问题:



首先,还没有忘记我们上次写的那个题目吗? (我估计也忘得差不多了)
来吧看代码:

#include<stdio.h>
#include<string.h>


int main(){

char str[5][20];
char *p = NULL,*q[5];//*q[5]相当于定义一个数值指针  通俗地讲就是定义了五个指针他们分别是*q[0],*q[2]...
int i,j;

for( i = 0 ; i < 5;i++){
scanf("%s",str[i]);//这里不能将str[i]写成str++;因为这里的str[i]相当于数组指针  
q[i] = str[i];   //现在在脑海里构想下,二维数组的样子//str[0]     这就是他的排布, str++他代表的是一维数组想想是不是
}       //str[1]     //当 i 加一时二维数组是往下走的 而str++所代表的则是往右走的
for( i=0; i<5-1; i++){       //str[2]    //所有改成str++是不对的  他们的类型不同:
for( j=0; j<5-1-i; j++){       //str[3]
if(strcmp(q[j],q[j+1]) > 0){                   //str[4]
p = q[j+1];
q[j+1] = q[j];
q[j] = p;
}
}
}
for( i = 0; i < 5; i++){
printf("%s\n",q[i]);//这里的输出为什么不是*q[i], 而是q[i],因为%s对应的就是地址而不是变量: 
}
return 0;
}
上面有没有发现我写了个    char *p = NULL;  这样的定义 就相当于说我将这块地址赋为了  零  地址;当你直接去访问它是系统是
                                            不允许的此时就会报错,但你定义为   char *p;此时没有告诉它你指针所指的位置
                                             如果运气好  可能你的代码会得到你想要的结果  但大多数情况 将一个值存入这个指针系统就会崩溃  他不会报错
                                             例: int *p;
                                                  *p = 5;
                                                  printf("%d",*p);
                                                  这时代码能通过编译  但一运行就崩溃了  原因就是因为将不该存东西的地方存了东西  p 这个指针变量
                                                  它里面存的地址不清楚,有可能当指针指向他时搞好就是系统不准访问的地址所以就崩溃了:








*** 
再来看一个问题
  #include<stdio.h>
#include<stdlib.h>


int main(){
int i,n,*p,maximum=-1,minimum = 150;
double average=0;


scanf("%d",&n);
p = (int*)malloc(n*sizeof(int));  //malloc 的使用在使用它时加上头文件  include<stdlib.h>   函数原型  指针变量 = (类型指针)malloc(变量个数*sizeof(变量类型))
for( i = 0 ; i < n;i++){          //每一个malloc都要有对应的free();他的作用就是将malloc得来的空间(内存)释放;
                 //小程序里面可能体现不出free的作用但是当某天  在大工程里面你不停的 malloc 不 free 运行不了多久你的系统就会异常终止
                                                  //因为申请了内存 在程序运行完  不释放掉他就一直站着这块内存久而久之你的计算机就没有内存空间可申请了所以报错


scanf("%d",&p[i]);  //等价于scanf("%d",p++);   此时是不是很疑惑为什么这个跟上面不一样吗;  如果有这样的疑惑那我不知道是 喜还是悲 
                        //scanf("%d",p++);        //在之前我有说过  malloc  来的  可以当做数组来用  还记得不  ;这里的数组肯定是一维的啦;  
}                                 //p++   就相当于  将他的地址向后一位  然后我们就可以依次存数了


                                                  *//当使用完后p++了   注意  注意  注意  这就是那天我们错的位置   并没有将他的  p   回到原来的首地址而是 p
                                                   //所在的最大 地址 加一  的位置上;  
 


for( i = 0; i < n;i++){




average += p[i];        //接着我们就在这里使用了p[i];  那当然错了啦    因为 p  不是最初的地址   而是我们累加后的地址
if(p[i] > maximum){             //所以当我们做完scanf("%d",p++);后 接着一行  因该将  p的地址   复原  那该怎么办呢?


                                                //先自己想想                                            p -= i;这就将他复原了
maximum = p[i];
}
if(p[i] < minimum){
minimum = p[i];
}
}


printf("average score is %lf\n",average/5);
printf("maximum score is %d\n",maximum);
printf("minimum score is %d",minimum);
free(p);                                         //free(申请来的指针变量(同样也是那个的首地址而不能将他已改变的指针变量的值给他free掉 ));
return 0;                                        //如果非要改变那个指针变量的值  那就再定义一个 相同类型的指针  然后将你重新定义的那个指针变量赋给与 malloc 来的首地址


}                                                        //通过改变重新定义的指针来达到你的目的  最后free 释放掉malloc  来的那个指针变量




















牛刀小试  :




     表达是(a)和(b)的求值过程有没有区别?如果有区别在那。假设offset的值为3.
                         int i[10];
                         int *p = &i[0];
                         int offset;


                         p += offset;(a)
                         p += 3;(b)


















下面的代码有没有问题  如果有的话,问题在哪?
                   int a[10];
                   int *pi;
                   
                   for( pi=&a[0]; pi < &a[10];)
                  *++pi = 0;


如果改正后 用指针的形式代表变量用printf输出






增加点知识 int i[10];
                         int *p = &i[0];
                         *p + 6;这个代表什么?  想想最后告诉你




不知道讲这么多   我讲没讲清楚  如果不 清楚的话要问   不要留疑问在心理


好了   上面那个*p + 6;意思是  先执行 *p  在加6;   书324 运算符优先级问题




多多理解   不懂就问   学问  是问出来的





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值