C语言:关于数组退化为指针

本文深入探讨了C语言中数组与指针的关系,解释了数组作为参数传递时的特性,包括数组退化为指针的情况及如何在函数中获取数组的实际大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

从一个小题下手,初步理解数组和指针的关系:

#include <stdio.h>
 
int size(char a[10])
{
    return sizeof(a);
}
 
int main(void)
{
    char a[] = {'C','h','i','n','a','\0'};
    char *p = "China";
    char *q = a;
    printf("sizeof(a)=%d\n", sizeof(a));  //sizeof(a)=6
    printf("sizeof(p)=%d\n", sizeof(p));  //sizeof(p)=4
    printf("sizeof(q)=%d\n", sizeof(q));  //sizeof(q)=4
    printf("size(a)=%d\n", size(a));      //size(a)=4
     return 0;
}
//在32位机的编译环境下,对C语言熟悉的人答案是不是很容易就看出来了。

 

基于本小题,主要考究以下几点:

  • 首先C语言里面不支持数组作为形参来进行调用,例如上述函数int size(char a[])实际上在进行编译时,是作为指针来处理的,所以上面的函数完全等价于int size(char *a);所以上面printf("size(a)=%d\n", size(a));  输出size(a)=4。
  • 数组作为参数传给函数时,传的是指针而不是数组,传递的是数组的首地址,如 fun (char[8]),fun(char [])都等价于 fun(char*)
  • 退化为指针;需要数组大小时,需要一个参数传数组名,另一个传数组大小

           void fun(int *a,size_t n);

仅在以下3种情况中,数组不会退化成指针

  1. 使用sizeof(a)的时候,所以上面sizeof(a)的结果为6字节
  2. 对数组名取地址操作:&a。&a的类型为pointer to array of 6 chars,而对字符串指针取地址结果为pointer to pointer to char.
  3. 使用字符串初始化数组的时候也不会退化。

其它情况都会退化成“指向数组首元素的指针”,比如:

  1. 数组名做函数参数时,a都会退化成&a[0]指针。如上面的size函数和printf函数中的a[]都是这种情况
  2. 二维数组,char s[10][8]数组的首元素(得理解这个首元素,从一维数组的角度看的)是一维数组s[0],因此退化成&s[0]指针

数组定义字符串和指针定义字符串的区别

  1. 使用数字定义的字符串只分配字符串所需的空间(上例中为6个字节),数字名没有单独的存储空间;使用指针定义字符串,除了字符串占用的空间,还要为指针变量分配对应的空间。
  2. 数组退化成指针为“常量指针”,不可更改,而直接指向字符串的指针可修改,如
char a[10] = "China";
char *p = "China";
a++;   // 错误的
p++;   // 正确的

在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。

如果想在函数内知道数组的大小,需要这样做:进入函数后用memcpy将数组复制出来,长度由另一个形参传进去

代码如下:

fun (unsigned char *p1,int len)
{
unsigned char* buf = new unsigned char[len+1];
memcpy(buf,p1,len);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值