C中的指针(2)

一些C语言指针的经典题目。

1.下列程序的输出结果

#include<stdio.h>

#include<stdlib.h>

intmain()

{

    int i=11;

    int const *p=&i;    //指向常量的指针,指针指向的值不能改变,但是可以改变指针的指向。

    p++;              //指针指向了一个不确定的内存空间。

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

    return 0;

}

解答:程序运行结果为一个不确定的值。

 2.下列代码合法的有

intf()

{

    int *a=new int(3);

    return *a;

}

合法,返回的值为3.

vector<int>f1()

{

    vector<int>v(3);

    return v;

}

合法

int*f2()

{

    int a[3]={1,2,3};

    return a;

}

不合法,a是定义在函数内部的,函数结束后空间就释放了。

voidf3(int *ret)

{

 int a[3]={1,2,3};

 ret=a;

 return;  

}  

不合法,指针ret最终还是被释放了。

 3.下面程序的输出是

#include<stdio.h>

#include<stdlib.h>

#include<iostream>

#include<string>

usingnamespace std;

char*f(char *str, char ch)

{

     char *it1 = str;

     char *it2 = str;

     while(*it2 != '\0')

     {

         while(*it2 == ch)

         {

           it2++;

         }

    *it1++ = *it2++;

     }

    return str;

}

 int main(int argc, char* argv[])

{

     char *a = new char[10];

     strcpy(a, "abcdcccd");

     cout<<f(a, 'c');

     return 0;

}

解答:abcdcccd

 4.指针形参经典问题

#include<stdio.h>

#include<stdlib.h>

#include<string>

voidGetMemory(char * p,int num)

{

 p=(char*)malloc(num);

}

intmain()

{

char*str=NULL;

GetMemory(str,100);

strcpy(str,"hello");

printf("%s\n",str);

return0;;

}

解答:程序结果出现了内存错误。参数传递是值传递,函数中为形参指针开辟了空间。单但是实际上没有为实参指针开辟空间。

解决方法:

(1)传递指针的指针

void GetMemory(char **p,int num)

{

 *p=(char*)malloc(num);

}

int main()

{

char *str=NULL;

GetMemory(&str,100);

strcpy(str,"hello");

printf("%s\n",str);

return 0;;

}

(2

char *GetMemory(char*p,int num)
{

 p=(char*)malloc(num);
return p;
}
int main()
{
  char *str=NULL;
  str=GetMemory(str,100);

strcpy(str,"hello");

printf("%s\n",str);

return 0;;

}

Tips:

(1)  变量做实参时,传值无法改变实参,传指针和引用可以改变实参。传指针的指针或者指针的引用才能改变指针。

(2)  C++中向函数中传递指针和传递指针的引用的区别:
 
如果是传递指针,那么会先复制该指针,在函数内部使用到的是复制后的指针,这个指针与原来的指针指向相同的地址,如果在函数内部将复制后的指针指向了另外的新的对象,那么不会影响原有的指针。所以要在函数中改变指针,必须传递指针的指针或者指针的引用。

5.返回引用
  int x=0;

   int &a(int &i)
     {
         i=-1;
         return x;
       }
        void main()
         {
           int j=10;
           a(j)=100;
         }
    结果:j=-1,x=100.

6.下面程序的输出

#include<stdio.h>
int main(void)

{
    inta[5][10];
   printf(“%d,%d,%d”,a,a+1,&a+1)
}
 分析:
a是指int a[10]的类型,&a是指a[5][10]的类型。
 指针运算的1代表的是指针类型的长度,因此a+1和&a+1中的1代表的长度分别为
4*10 和4*5*10
 假设a 的首地址为1310392,
则a+1为 1310432,
&a+1为 1310592

 7. 定义一个宏,求出给定结构中给定成员的偏移量

#define OFFSET(TYPE,MEMBER)(size_t)(&(((TYPE*)0)->MEMBER))
把0地址转化为TYPE结构的指针,然后读取该结构中MEMBER成员的指针,并且将其强制转换为size_t类型。

 8.以下代码在低位优先平台的输出结果

#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);
printf(“%x,%x”,ptr1[-1],*ptr2);
}
 
&a代表的是整个数组,a代表数组的第一个元素。
 

(1)     ptr1=(int*)(&a+1),ptr1指到了数组的末尾,

        ptr1[-1]向低地址移动4个字节,为a[4]=5。
 
(2)       ptr2=(int*)((int)a+1)
        a已经强制转换成了整形,a+1已经不是指针运算了,(int*)((int)a+1)指向首地址的下一个字节。
  内存低地址                                内存高地址
 01  00  00  00  02  00  00 00   03   00  00  00 
 则(*ptr2)=20 00 00 00

 

 

 

 

 

 

 



 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值