数组与指针

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]。

posted @ 2021-06-28 13:12  hitzzq  阅读(33)  评论(0编辑  收藏  举报