数组和指针有什么区别

char s1[] = "hello";

char* s2 = "hello";

  • 编译器在栈上为数组s1分配连续内存,数组的内容也就是元素可以修改
  • s2中的hello是字符常量,在内存分配上,分配到了rodata段,也就是只读区,指针s2在栈上分配内存,并指向这个只读区的地址
  • s2本身是指针,可以改变,即可以指向另一个字符串,但字符串字面值的内容不可以被修改

所以

s1[0] = 'H'; //正确
s2[0] = 'H'; // 错误,段错误
  • 其次,s1是数组,其大小是整个数组的大小:6,s2是指针,大小是指针的大小:8
  • s1本身是数组名,是第一个元素的地址,是常量,s2本身是指针,是变量,这就好比指针常量和常量指针

所以

s1++; //错误
s2++; // 正确

看如下代码

char* func(){
    char s1[] = "hello";
    char* s2 = "hello";
    return s1;
    return s2;
}

哪个可以被正确return呢

s1 是一个局部字符数组,定义在栈上,这个数组的生命周期是函数 func 的作用域。一旦函数返回,这个数组的内存会被释放,返回指向这个数组的指针会导致指针悬空。

s2 是一个指针,指向一个字符串常量,字符串常量的生命周期贯穿程序的整个运行期。因此,返回这个指针是安全的

结论:

char* func() {
    char s1[] = "hello";
    char* s2 = "hello";
    // return s1;  // 不安全
    return s2;     // 安全
}

所以

通常不返回字符数组,而是

        函数参数中传递一个预分配的字符数组,然后在函数中填充它。

        使用string自动管理内存

 ps:传入为char a[10]这样的char * 型数组,函数参数为char * 类型接收,同理返回char a[10]用char * 接收, 此时要接受char *的函数参数时,是声明char *的指针指向它的。

番外:

写一个用指针swap函数交换值

void swap(int* a, int* b){
    int temp = *b; // 必须用int的临时变量存储b的值,不能使用int* temp = b;
    *b = *a;
    *a = temp;
}

写一个用指针swap函数交换指针

void swap(int** a, int** b){
    int* temp = *b; // 必须用int*的临时变量存储b的值,不能使用int** temp = b;
    *b = *a;
    *a = temp;
}

 完整代码:

#include <cstring>
#include <iostream>
void func(char* buffer, size_t bufferSize) {
    const char* message = "hello";
    if (bufferSize >= strlen(message) + 1) {
        strcpy(buffer, message);
    }
}

void swap(int** a, int** b){
    int* temp = *b;
    *b = *a;
    *a = temp;
}


char* func(){
    char s1[] = "hello";
    char* s2 = "hello";
    return s1;
    // return s2;
}
int main() {
    char buffer[6];  // 预分配数组
    func(buffer, sizeof(buffer));
    std::cout << buffer << std::endl;  // 输出 buffer 内容
    
    int a = 1;
    int* aa = &a;
    int b = 2;
    int* bb = &b;
    swap(&aa, &bb);
    std::cout << a <<"  " << b  <<"  " << *aa <<"  " << *bb << std::endl;
    char* str = func();
    std::cout << str << std::endl; // 可能输出垃圾值或程序崩溃
    std::cout << "111" << std::endl; 
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值