C/C++数组名与指针的区别详解

1.数组名不是指针
我们看下面的示例:

#include <iostream> 
int main() 
{ 
    char str[10]; 
    char *pStr = str; 
    cout << sizeof(str) << endl; 
    cout << sizeof(pStr) << endl; 
    return 0; 
}

输出结果:
10
4
由输出结果可知,数组名并不是指针。

2.数组名神似指针
上例我们证明了数组名不是指针,但第5行,char *pStr = str;
程序将数组名直接赋给指针,这显得数组名又的确是个指针!
我们还可以发现数组名显得像指针的例子:

#include <string.h> 
#include <iostream> 
int main(int argc, char* argv[]) 
{ 
    char str1[10] = "I Love U"; 
    char str2[10]; 
    strcpy(str2,str1); 
    std::cout << "string array 1: " << str1 << std::endl; 
    std::cout << "string array 2: " << str2 << std::endl; 
    return 0; 
}

标准C库函数strcpy的函数原形中能接纳的两个参数都为char型指针,
而我们在调用中传给它的却是两个数组名!
函数输出:
string array 1: I Love U
string array 2: I Love U

数组名再一次显得像指针!
既然数组名不是指针,而为什么到处都把数组名当指针用?
于是乎,许多程序员得出这样的结论:数组名(主)是(谓)不是指针的指针(宾)。

3.揭密数组名
现在到揭露数组名本质的时候了,先给出三个结论:
数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;
数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;
指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址!

1)数组名指代一种数据结构:数组

现在可以解释为什么第1个程序第6行的输出为10的问题,
根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的char型数组,
所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。
再看:

int intArray[10]; 
cout << sizeof(intArray) ; 

输出结果
40

2)数组名可作为指针常量
根据结论2,数组名可以转换为指向其指代实体的指针,
所以程序1中的第5行数组名直接赋值给指针,程序2第7行直接将数组名作为指针形参都可成立。

下面的程序成立吗?

int intArray[10]; 
intArray++;

读者可以编译之,发现编译出错。
原因在于,虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。

而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,
在WIN32平台下,sizeof操作的结果都是4。

3)数据名可能失去其数据结构内涵

到这里似乎数组名魔幻问题已经宣告圆满解决,但是平静的湖面上却再次掀起波浪。
请看下面一段程序:

#include <iostream> 
void arrayTest(char str[]) 
{ 
    std::cout << sizeof(str) << std::endl; 
} 
int main() 
{ 
    char str1[10] = "I Love U"; 
    arrayTest(str1); 
    return 0; 
}

输出结果

4

不可能吧?
一个可怕的数字,前面已经提到其为指针的长度!
结论1指出,数据名内涵为数组这种数据结构,在arrayTest函数体内,str是数组名,那为什么sizeof的结果却是指针的长度?
这是因为:
数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;
很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

所以,数据名作为函数形参时,其全面沦落为一个普通指针!
它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

以上就是结论4。

补充结论:

 1、数组名就是第一个元素的地址,数组名就是地址,但绝对不是指针。

关于数组名和指针的区别可以参考一下链接:

https://blog.csdn.net/Betty2017/article/details/79652258

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: memset()函数是C/C++语言的一个库函数,可以用于将一段内存空间的内容设置为指定的值。 memset()函数的原型为: ```c void *memset(void *s, int c, size_t n); ``` 其,s是指向要设置的内存的指针;c是要设置的值,通常是一个无符号字符或者零;n是要设置的内存空间的大小。 memset()函数的作用是将一段内存空间的每个字节都设置为相同的值。可以用于初始化内存,或者将内存的内容清零。 使用memset()函数需要注意以下几点: 1. memset()函数只能用于字符数据类型或者无符号整型数据类型,即只能设置1字节大小的值。 2. 使用memset()函数时,需要知道要设置的内存空间的大小,以防止超出边界进行内存越界操作。 3. memset()函数是按字节进行设置的,所以对于非字符类型数据(如整数或浮点数),可能造成数据不符合预期。 示例代码: ```c #include <string.h> int main() { int arr[5]; memset(arr, 0, 5 * sizeof(int)); // 将arr内存空间设置为0 char str[20]; memset(str, 'A', 19); // 将str内存空间设置为'A' str[19] = '\0'; // 末尾添加'\0',形成一个字符串 return 0; } ``` 总之,memset()函数是一个能快速设置内存空间内容的函数,可以方便地进行内存初始化和内存清零操作。 ### 回答2: memset()函数是C语言的一个库函数,其原型如下: void *memset(void *ptr, int value, size_t num); memset()函数的作用是将指定内存空间的值设置为指定的值。其,ptr表示要设置的内存空间的起始地址,value表示要设置的值,num表示要设置的字节数。 memset()函数的返回值为void指针类型,即可以接受任何类型的指针。 使用memset()函数可以在一次调用批量设置内存空间的值,提高效率和代码的简洁度。 例如,下面的代码片段就是使用memset()函数将数组arr的所有元素设置为0: int arr[10]; memset(arr, 0, sizeof(arr)); 由于memset()函数设置的是字节数据,所以在设置非字符类型数据时需要小心。以一个int型数组arr为例,使用memset()函数将其所有元素设置为-1可能会出现错误。因为在某些机器上,-1的二进制表示并不是所有字节全为1,这会导致memset()函数设置的结果并非预期。 对于字符数组或字符串,可以使用memset()函数设置为0,即'\0',也可以使用strcpy()函数进行单个字符赋值,这样更为安全可靠。 总之,memset()函数是一个实用的函数,可以批量设置内存空间的值,提高代码的执行效率和简洁度。在使用时,需要注意数据类型和数据源的合法性,以避免出现错误。 ### 回答3: memset()函数是C/C++语言的一个库函数,主要用来对一段指定内存空间进行初始化。 其函数原型为: void* memset(void* ptr, int value, size_t num); 第一个参数ptr是一个指向某一块内存区域的指针,用来指定待初始化的内存空间。 第二个参数value是一个整数值,用来指定待初始化的值,其最常用的是0。 第三个参数num是一个整数值,用来指定待初始化的内存空间的字节数。 memset()函数的作用是将ptr指向的内存空间的每个字节都设置为value指定的值。一般来说,value为0时,可以用来将内存空间清零。 memset()函数通常用于对数组、字符串或结构体等数据类型的初始化。例如,当我们声明一个数组或字符串后,需要将其所有元素或字符都初始化为0,可以使用memset()函数。 以下是一个使用memset()函数进行数组初始化的示例: int num[5]; memset(num, 0, sizeof(num)); 以上代码将会把num数组的所有元素都初始化为0。 需要注意的是,memset()函数只能用来设置每个字节的值,并不能对较大的数据块进行初始化。此外,在使用memset()函数时,需要确保待初始化的内存空间不受限制并且是可访问的,否则可能会引发错误。 总结起来,memset()函数是C/C++常用的一个函数,主要用来对一段指定的内存空间进行初始化,提高程序的可读性和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值