菜单开关

周梦康 发表于 2017-09-28 1961 次浏览 标签 : C语言快速入门

实验1

假如我们有一个函数a,他的返回值是一个int,然后我们需要在main函数里接收a的返回值。

#include <stdio.h>

int a();

int main(int argc, char const *argv[]) {
    
    printf("%d",a());

    return 0;
}

int a()
{
    int b = 1;
    return b;
}

实验2

现在改为返回一个char *字符串

#include <stdio.h>

char * a();

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

    printf("%s",a());

    return 0;
}

char * a()
{
    char *b = "string";
    return b;
}

实验3

如果是返回一个字符数组或者一个int数组呢?

#include <stdio.h>

char * a();

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

    printf("%s",a());

    return 0;
}

char * a()
{
    char b[] = {'a','b','\0'};
    return b;
}

新人困惑:为什么明明是数组,却要返回一个指针呢?

数组在 C 语言里是无法返回的,假设可以返回数组,那么返回返回值类型如何写呢?既然是函数都是动态的,返回数组的长度也是动态的,所以只能返回一个指针。

因为数组是连续的内存,而指针的类型正好可以用来计算数组各个元素内存的步长(需要偏移的字节数),这样就可以依次取出数组中的值了。这里我们用了一个\0来标识字符的结束。

编译出错,为什么呢?

$ gcc test.c -o test
test.c:15:12: warning: address of stack memory associated with local variable
      'b' returned [-Wreturn-stack-address]
    return b;
           ^
1 warning generated.

因为b是在栈上分配的,当函数执行完毕之后就内存就回收了,所以返回b的首地址是没有意义的,里面的数据已经被清空。这就是局部变量的作用域。

相比之,实验2也是返回的指针,为什么就没问题呢?
因为字符串是在常量区申请的内存,函数结束后,内存不会回收。
参考 字符串初始化的原理

堆内存的使用

假如就是要返回数组,那应该怎么办呢?那么堆内存就可以派上用场了,因为堆上内存是使用者自己来控制内存申请和释放。

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

char *a();

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

    char *c = a();
    printf("%s", c);
    free(c);// 记得释放内存哦

    return 0;
}

char *a() {
    char *b = (char *) malloc(sizeof(char) * 3);
    b[0] = 'a';
    b[1] = 'b';
    b[2] = '\0';

    return b;
}

realloc 内存的使用

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

int main(int argc, char const *argv[]) {
    int sockfd;
    size_t mem_size = 4096;
    int length = 0;
    ssize_t len;
    
    ...

    char    *buf      = (char *) malloc(mem_size * sizeof(char));
    char    *response = (char *) malloc(mem_size * sizeof(char));
    
    while ((len = read(sockfd, buf, 1)) != 0) {
        if (length + len > mem_size) {
            //动态内存申请, 因为无法确定响应头内容长度
            mem_size *= 2;
            response = (char *) realloc(response, sizeof(char) * mem_size);
        }

        buf[len] = '\0';
        strcat(response, buf);
    }

    return 0;
}

评论列表