指针和数组笔试题

int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); // 16 当数组名在sizeof中单独使用时代表的是整个数组;
printf("%d\n",sizeof(a+0)); // 4 此时a代表数组首元素地址(指针),所以大小为4
printf("%d\n",sizeof(a)); //4 a代表数组首元素地址(指针),在进行解引用代表整形 元素‘1’占4个字节
printf("%d\n",sizeof(a+1));//4 a代表数组首元素地址(指针),+1指向数组中下一个元素地址,只要是地址就占4个字节。
printf("%d\n",sizeof(a[1]));//4 a[1]=1,代表整形占4个字节
printf("%d\n",sizeof(&a));4 &a代表数组地址,他在数值上与数组首元素相等,但所代表的含义不同。但是只要是地址(指针)就占4个字节
printf("%d\n",sizeof(
&a)); //**16 &a代表数组地址,对数组地址解引用,代表整个数组长度。所以4
4=16**
printf("%d\n",sizeof(&a+1));// 4 &a代表数组地址,+1代表下一个数组的地址
printf("%d\n",sizeof(&a[0]));// 4 &a[0]代表数组首元素地址,
printf("%d\n",sizeof(&a[0]+1));// 4 &a[0]代表数组首元素地址,+1 代表数组下一个元素的地址
注意区分指针与指针变量,指针就是地址,指针变量是变量,有空间 ,内容,地址。该变量空间中放的是地址。 !只要是地址(指针)就占4个字节,在32位平台下。
//
字符数组 char arr[] = {‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
printf("%d\n", sizeof(arr)); //6 当数组名在sizeof中单独使用时代表的是整个数组;
printf("%d\n", sizeof(arr+0));// 4 arr字符数组首元素地址
printf("%d\n", sizeof(arr));// 1 arr代表字符数组首元素所以大小为1
printf("%d\n", sizeof(arr[1]));
//1 arr[1]代表字符数组首元素所以大小为1
printf("%d\n", sizeof(&arr)); // 4 &arr代表字符数组地址,只要是地址就占4个字节
printf("%d\n", sizeof(&arr+1)); // 4 &arr+1&a代表字符数组地址,+1代表下一个字符数组的地址
*
printf("%d\n", sizeof(&arr[0]+1));// 4 &arr[0]代表字符数组首元素地址,+1 代表字符数组下一个元素的地址**
注意:strlen是函数,要进行传参降维,降维成对应的指针。
printf("%d\n", strlen(arr));// len>=6,strlen进行计算时遇到‘/0’结束,所以它所计算的值最小为6.
printf("%d\n", strlen(arr+0)); // 同上
printf("%d\n", strlen(*arr));// 编译报错,传参类型不符合
printf("%d\n", strlen(arr[1]));//编译报错,传参类型不符合
printf("%d\n", strlen(&arr));//*有告警,但能通过 len>=6 因为&arr相当于char(p)arr[]类型,是一个数组指针。
printf("%d\n", strlen(&arr+1)); //*有告警,但能通过 len-6 因为&arr相当于char(p)arr[]类型,是一个数组指针,+1指向下一个数组。
printf("%d\n", strlen(&arr[0]+1));// len-1

   ****char arr[] = "abcdef";****
    printf("%d\n", sizeof(arr)); //7,,字符串数组包括‘/0,所以大小为7
    printf("%d\n", sizeof(arr+0));//4  arr+0代表数组首元素地址(指针),所以大小为4
     printf("%d\n", sizeof(*arr)); // 1 *arr代表字符a,所以大小为1
      printf("%d\n", sizeof(arr[1]));// 1 arr[1]==b,所以大小为1
       printf("%d\n", sizeof(&arr)); // 4 代表数组的地址,大小为4
       printf("%d\n", sizeof(&arr+1)); // 4 代表下一个数组的地址,大小为4
        printf("%d\n", sizeof(&arr[0]+1)); // 4 代表数组第二个元素的地址,大小为4

printf("%d\n", strlen(arr)); // 6 字符串数组包括‘/0,strlen进行计算时遇到‘/0’结束,所以为6
printf("%d\n", strlen(arr+0)); // 6 同上
printf("%d\n", strlen(*arr)); // 编译报错,传参类型不符
printf("%d\n", strlen(arr[1]));// 同上
printf("%d\n", strlen(&arr)); // 随机值, 传参为数组指针,可能警告
printf("%d\n", strlen(&arr+1));同上
printf("%d\n", strlen(&arr[0]+1)); // 5 从字符串数组第二个元素算起到‘/0结束 ,不包括‘/0

char *p = "abcdef"; 
printf("%d\n", sizeof(p)); // 4  p是首元素的地址,是指针变量,所以大小为4
 printf("%d\n", sizeof(p+1)); // p+1是第二个元素地址,是指针,所以大小为4
  printf("%d\n", sizeof(*p)); // 指针解引用等于首元素,所以大小为1
   printf("%d\n", sizeof(p[0]));// p[0]=a 大小为1
    printf("%d\n", sizeof(&p)); // 4 二级指针,大小为4
    printf("%d\n", sizeof(&p+1));// 同上
     printf("%d\n", sizeof(&p[0]+1));//第二个元素地址,大小为4
printf("%d\n", strlen(p));//6
 printf("%d\n", strlen(p+1));// 5
  printf("%d\n", strlen(*p));  // 编译报错
  printf("%d\n", strlen(p[0]));  // 编译报错
   printf("%d\n", strlen(&p)); // 随机值
   printf("%d\n", strlen(&p+1)); // 随机值
   printf("%d\n", strlen(&p[0]+1));// 5
   

```c
二维数组 int a[3][4] = {0}; 注意:二维数组,也可以看作一维数组,只不过数组里面放的元素是数组。这样理解有助于下面题目的解答
printf("%d\n",sizeof(a)); // 48  12*4=48
printf("%d\n",sizeof(a[0][0]));// 4 a[0][0]=0;代表数组中首位元素
 printf("%d\n",sizeof(a[0]));// 16 代表的数组首“元素”地址,这个元素是一个数组地址,所以 4*4
  printf("%d\n",sizeof(a[0]+1));// 4 a[0]代表的数组首“元素”地址,这个元素地址是一个数组地址,+1 代表元素里面的元素的地址。 
   printf("%d\n",sizeof(*(a[0]+1)));//4 同上 ,只不过对上面进行解引用,所以是元素里面的元素 大小为4
    printf("%d\n",sizeof(a+1)); //4 a+1代表数组中第二个元素的地址,大小为4
    printf("%d\n",sizeof(*(a+1)));//16 *(a+1)) 解引用代表数组中第二个“元素”,而数组中第二个“元素"是一个数组.4*4
     printf("%d\n",sizeof(&a[0]+1));//4  表数组中第二个元素的地址,大小为4
     printf("%d\n",sizeof(*(&a[0]+1)));//16 数组中第二个“元素”,而数组中第二个“元素"是一个数组.4*4
     printf("%d\n",sizeof(*a)); //16 数组中第一个“元素”,而数组中第一个“元素"是一个数组.4*4
```printf("%d\n",sizeof(a[3])); //16 越界访问,但能算出长度为16。数组中第4个“元素”的地址,而数组中第4个“元素"是一个数组地址.
总结: 数组名的意义: 1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
 2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
 3.  3. 除此之外所有的数组名都表示首元素的地址

int main()
 {
     int a[5] = { 1, 2, 3, 4, 5 }; 
        int *ptr = (int *)(&a + 1);
            printf( "%d,%d", *(a + 1), *(ptr - 1)); 
               return 0;
                } //结果为2 和 5   (&a + 1)是一个指向下一个数组起始地址的数组指针,加上(int *)强转为整形指针,对其进行解引用,就是5
           
struct Test 
{   
 int Num;   
  char *pcName;   
   short sDate;    char cha[2]; 
      short sBa[4];
       }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少?
        int main()
         {   
          printf("%p\n", p + 0x1);  // 0x100014 加1 加上结构体大小20字节
          printf("%p\n", (unsigned long)p + 0x1);  // 0x100001  unsigned long 进行强转,转化为整形
          printf("%p\n", (unsigned int*)p + 0x1); //  0x100004  unsigned int*  进行强转,转化为整形指针。 指针+1 是加上所指向类型的大小
           return 0; 
           }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值