c语言最大跨度值五个数组的,牛客网C++刷题一

1.分析下面代码有什么问题?

void test1()

{

char string[10];

char* str1 = "0123456789";

strcpy( string, str1 );

}

解:字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;

代码本身没有错误,如果将str1拷贝到string中,string的长度会增加,并且也可以正确的输出string。(c、java代码都测试过,没有问题)

但是存在潜在的危险,string定义的长度是10,而拷入str1之后string的长度增为11,也就是说,在内存中,如果紧接string之后有内容,将被覆盖,这样会导致string之后的内存存取错误。

知识点:

允许用字符串字面值对字符数组初始化,\0也会拷贝进去。

编译器会自动把数组名字替换为指向数组首元素的指针。(详细看下1)

strcpy为c风格字符串的函数,定义在头文件cstring中,strcpy(p1,p2)将p2拷贝给p1,返回p1,连字符串结束标志\0也一起copy。

存在问题:

string不能用作变量名,string是c++中的标准库类型。

str1是一个指向字符的指针/字符数组,字符串字面值"0123456789"的长度为11,strcpy函数将str1拷贝给string,但string大小为10,str大小为11,导致数组越界。

补充:

1.C/C++里面的数组名字会退化为指针,所以数组名str1实际指的是数组的第一个元素的地址。而数组名作为指针来讲有特殊性,它正在它所指向的内存区域中,&str1的值和str1的数值是相同的。

2.strcpy函数的实现是以’\0’判定拷贝结束的,并且会给目标字符串结尾加一个’\0’

3.先定义一个一维数组

int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

一、数组名是什么

数组名经常被隐式转换为指向数组首元素的指针常量:

数组名不是指针,但大多数使用到数组名的地方,编译器都会把数组名隐式转换成一个指向数组首元素的指针来处理。只有两种情况下例外:

1.对数组名使用sizeof运算符

sizeof(a)

这将会得到整个数组所占的内存大小,a是长度为10的int(4字节)数组,运算结果是40。此时a代表的是数组所占用的那一整块内存。

2.对数组名取地址

&a

运算结果是数组的地址。注意,数组的地址和数组首元素的地址是不同的概念,尽管二者存储的值是相同的,但它们的跨度是不同的,不信的话,对它们进行解引用或比较一下a+1和&a+1,你就会明白了。

二、下标引用

除了上面说的两种例外,其他情况下编译器都将数组名隐式转换成指针常量。比如使用下标引用数组元素:

a[3] // 自动转换成下面的表达式

*(a + 3)

a的值被转换成指针常量,指向第一个元素,向右移动3 * sizeof(int)个字节,然后解引用,便得到了第4个元素的内容。

因为第一种写法会自动转换成第二种,这个过程需要一些开销,所以我们说第二种写法通常效率会高一些。

三、数组名的类型

以数组名a为例,a的类型是:

int * const a;

数组的类型取决于数组元素的类型:如果它们是int类型,那么数组名的类型就是“指向int的指针常量”;如果它们是其他类型,那么数组名的类型就是“指向其他类型的指针常量”。(出自《C和指针》第141页)

这里需要补充两点,&a的类型和二维数组名的类型。

在接下来的第四点会详细解释&a的含义,这里先给出结论,&a是指向数组的指针,而&a的类型是int ()[10]。

然后二维数组的类型同样取决于数组元素的类型,假设有二维数组int b[10][20]

因为C语言的多维数组实际上是一维数组,二维数组实际上只是一个一维数组,只不过里面每个元素又是一个一维数组而已。所以b的类型是int ()[20],而&b的类型是int (*)[10][20]

四、a 和 &a

一个有趣的事实是,a 和 &a 的值是相同的。

**&a 中的a代表整个数组,而不是指向数组首元素的指针常量。 **

“取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量值的指针”(出自《C和指针》第142页)。

通过四条语句可以更好地理解它们的关系:

我知道%p用来输出地址,但为了方便观察我改用%d以整数10进制形式输出

printf("a = %d\n", a); //19920908

printf("a + 1 = %d\n", a + 1); //19920912

printf("&a = %d\n", &a); //19920908

printf("&a + 1 = %d\n", &a + 1); //19920948

可以很直观地看出a和&a的区别了。

a指向首元素,右移一位,地址增加了4字节,也就是一个int的长度;

&a指向数组,右移一位,地址增加了40字节,相当于指向了下一个数组(可能并不存在),这在C++里称为尾后指针。

五、获取数组元素个数

用数组的总字节长度除以单个元素的字节长度得到元素个数

sizeof(a) / sizeof(*a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值