数组与指针
sizeof只能计算出静态数组的大小,无法计算动态分配或外部数组大小。
7.请写出以下代码输出结果
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
int main(void) {
printf("%d \r\n", (str1 == str2));
printf("%d \r\n", (str3 == str4));
printf("%d \r\n", (str5 == str6));
printf("%d \r\n", (str7 == str8));
system("pause");
return 0;
}
输出结果 0 0 1 1
原因:str1, str2, str3, str4属于数组变量,都有各自的内存空间;str6, str7, str8, str9属于指针,它们都指向了相同的常量区域。
8.以下代码的两个sizeof用法有问题吗?
static void UpperCase(char str[]) {
for(int i = 0; i < sizeof(str) /sizeof(str[0]); ++i) {
if('a' <= str[i] && str[i] <= 'z') {
str[i] -= ('a' - 'A');
}
}
}
int main() {
char str[] = "aBcDe";
printf("str 长度 = %d\r\n", sizeof(str) / sizeof(str[0]));
UpperCase(str);
printf("%s\r\n", str);
system("pause");
return 0;
}
UpperCase函数内的sizeof用法有问题。
sizeof只能计算出静态数组的大小,无法计算动态分配或外部数组大小。
函数外部的str是一个静态数组,其大小为6;
函数内的str实际只是一个指向字符串的指针,因此,其计算的是一个指针的大小:4个字节。
9.请写出下列代码的输出结果
int main() {
int a[5] = {1,2,3,4,5};
int *ptr = (int *)(&a + 1);
printf("%d,%d\r\n", *(a + 1), *(ptr - 1));
system("pause");
return 0;
}
输出:2,5
原因:*(a + 1)就是a[1],*(ptr - 1)就是a[4]
&a + 1不是数组首地址+1,系统会默认加一个数组a的偏移(这里是偏移了一个数组的大小,本数组大小为5个int)
int *ptr = (int *)(&a + 1);prt实际就是&(a[5]),也就是a + 5;
原因如下:
&a是数组指针,其类型为int(*)[5];
指针加1,要根据指针的类型加上一定的值,不同类型的指针加1之后增加的大小不同。
a是长度为5的int的数组指针,所以要加5 * sizeof(int)
所以,ptr实际是&a[5]。
但是ptr的类型与&a的类型是不同的,因此ptr – 1只会减去sizeof(int *)
a与&a的地址是一样的,但是它们所表示的意义不同。
a是数组首地址,也就是a[0]的地址;
&a是对象(数组)首地址;
a+1是数组下一个元素的地址,即a[1];
&a+1是下一个对象的地址,即a[5]。