现在的位置: 首页 > 综合 > 正文

参数 指针

2017年12月24日 ⁄ 综合 ⁄ 共 2436字 ⁄ 字号 评论关闭

一、对参数指针的地址修改

参数的地址是可以修改的,修改后的地址是不可能传回给调用处的指针变量。

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

int subFunc(int arr[3]);

//交换两整数
void change(int *data1, int *data2) {
    int *temp;

    //交换两数的地址
    temp = data1;
    data1 = data2;    //修改参数1的地址
    data2 = temp;     //修改参数2的地址

    //交换后的地址在函数内没问题,但不能传回主程序
    printf("change:data1=%d, data2=%d\n", *data1, *data2);

    return ;
}

//动态获得内存                             //|  //改为如下内容便可以传回主程序
void getMemory(int size, char *str) {      //|  char *getMemory(int size) {
    //动态分配的内存地址赋给str            //|
    str = (char *)malloc(size);            //|      return (char *)malloc(size);
                                           //|
    return ;                               //|  }
}                                          //|
                                           //|  //主程序的调用也得改成: p = getMemory(40) ;
int main(void)
{
    int x = 25, y = 87 ;

    change(&x, &y);
    printf("main:x=%d, y=%d\n", x, y);    //x,y未得到交换

    getMemory(40, p);    //p未得到内存
    strcpy(p, "这是小雅的C语言教程");    //这句有错,注释之后才能得到上图结果
    free(p) ;

    return 0;

上面的错误是将消亡的地址返回,修正的方法可以考虑2种,一是将函数中的数组改为静态的。另一种办法是再动态申请内存。这样修改之后固然正确,但如果主程序中的rst改为数组,结果又怎样呢?这将导致编译错误。因为数组的地址不能被修改。

二、用局部变量的地址作返回值

#include <stdio.h>

int *setData(void) {
    int arr[3] ;  //|   static int arr[3] ;

    arr[0] = 10 ;
    arr[1] = 35 ;
    arr[2] = 48 ;

    return arr ;  //局部变量随函数结束而消亡,因此,返回之后是不正确的
}

int main(void)
{
    int i ;
    int *rst ;

    rst = setData();
    for (i=0; i<3; i++) {
        printf("%3d\n", rst[i]);
    }

    return 0;
}

三、双重指针作参数

上面第一个例子讲到,不能把指针的地址传给调用处的变量,但实际编程时的确有这种需求,希望调用一个函数,使得原来的空指针变成有数据内容的指针。

这其实不难实现,大家只要比较一下以前讲到的基本类型(譬如int)作参数时,不能通过参数返回内容,我们就改成“int *”这样的指针类型作参数,从而解决这个问题。现在我们只要用双重指针便同样可以解决指针的地址传送的问题。但要注意:“int *”作参数,调用时用“&变量”;“int
**”作参数,调用时用“&指针变量”。

#include <stdio.h>
#include <stdlib.h>

void setData(int **ptr) {
    int *p = (int *)malloc(3 * sizeof(int));

    p[0] = 10, p[1] = 35, p[2] = 48 ;
    *ptr = p;  //注意:是将申请的内存地址赋给*ptr

    return ;
}

int main(void)
{
    int i ;
    int *data = NULL ;

    //这句有错,应该用指针变量data的地址作参数
    setData(data);  //|   setData(&data);

    for (i=0; i<3; i++) {
        printf("%3d\n", data[i]);
    }

    return 0;
}

void GetMemory(char *p)
{
    p = (char *)malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}

请问运行Test函数会有什么样的结果?

答:程序崩溃。

因为GetMemory并不能传递动态内存,

Test函数中的 str一直都是 NULL。

strcpy(str, "hello world");将使程序崩溃。

char *GetMemory(void)
{
    char p[] = "hello world";
    return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetMemory();
    printf(str);
}

请问运行Test函数会有什么样的结果?

答:可能是乱码。

因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。

void GetMemory2(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");
    printf(str);
}

请问运行Test函数会有什么样的结果?

答:

(1)能够输出hello

(2)内存泄漏

void Test(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, “hello”);
    free(str);
    if(str != NULL)
    {
        strcpy(str, “world”);
        printf(str);
    }
}

请问运行Test函数会有什么样的结果?

答:篡改动态内存区的内容,后果难以预料,非常危险。海姹网(网址:http://www.seacha.com),标签:C / C++程序员面试的一份试题, 指针变量,sizeof,ifndef

因为free(str);之后,str成为野指针,

if(str != NULL)语句不起作用。

 

【上篇】
【下篇】

抱歉!评论已关闭.