C语言——指针和数组名含义的辨析

指针和数组的题目辨析

一、

c 复制代码
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//1.
printf("%d\n",sizeof(a+0));//2.
printf("%d\n",sizeof(*a));//3.
printf("%d\n",sizeof(a+1));//4.
printf("%d\n",sizeof(a[1]));//5.
printf("%d\n",sizeof(&a));//6.
printf("%d\n",sizeof(*&a));//7.
printf("%d\n",sizeof(&a+1));//8.
printf("%d\n",sizeof(&a[0]));//9.
printf("%d\n",sizeof(&a[0]+1));//10.

首先强调sizeof是一个操作符(也是一个关键字),用于获取一种数据类型或一个变量所占用的字节数。

在上述代码中创建了一个整型数组a,存放了四个整型数据。(注:代码后面注释为代码所在行数,并无其他含义)

  1. 在该语句中,a是数组名,单独放在sizeof中表示计算整个数组的大小,也就是整个数组所占字节数。该数组是整型数组,一共存放四个元素,那么sizeof(a) = 4*4 = 16。
  2. 我们知道数组名指向的是数组中第一个元素的地址,在该语句中数组名并不是单独放在sizeof当中,而是sizeof(a+0),这表示a+0是一个地址,那么它的返回值便是4/8(在32位机器中一个地址所占空间大小是4字节,而在64位机器中一个地址所占空间大小为8字节)
  3. a是数组名指向数组中首元素的地址,*a就代表a数组中首元素,它是一个整型,当然为4字节大小。
  4. 该语句与2.相同,a没有单独放在sizeof当中,而是(a+1),这代表a+1是一个地址,并且指向的是数组中第二个元素的地址。那么返回值应该是4/8(在32位机器中一个地址所占空间大小是4字节,而在64位机器中一个地址所占空间大小为8字节)。
  5. sizeof(a[1]),a[1]代表数组中第二个元素,其实a[1] = *(a+1),不难看出a[1]是对数组中元素进行访问,且访问的是第二个元素,那么返回值就是4。
  6. sizeof(&a),&a表示对整个数组取地址,&a本质上是一个地址,那么它所占字节数就为4/8。
  7. sizeof(* &a):* &a表示先取出整个数组的地址(即&a),然后再对(&a)解引用,由于&a指向的是整个数组的内容,那么对(&a)解引用就是访问了整个数组,那么返回值就是整个数组的大小,即16.
  8. sizeof(&a+1):(&a+1)代表取出整个数组的地址,然后+1跳过整个数组,但本质上(&a+1)仍是一个地址,那么它的返回值便是4/8。
  9. sizeof(&a[0]):(&a[0])就是取出了数组中第一个元素的地址,那么一个地址的返回值是4/8 。
  10. sizeof(&a[0]+1):(&a[0]+1)表示取出首元素的地址然后+1跳过该元素,所以(&a[0]+1)是指向第二个元素的地址,返回值是4/8。
    总结:想要知道sizeof()返回值,最重要的是要弄清sizeof()里面放的数据的数据类型是怎样的。

二、

c 复制代码
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//1.
printf("%d\n", sizeof(arr+0));//2.
printf("%d\n", sizeof(*arr));//3.
printf("%d\n", sizeof(arr[1]));//4.
printf("%d\n", sizeof(&arr));//5.
printf("%d\n", sizeof(&arr+1));//6.
printf("%d\n", sizeof(&arr[0]+1));//7.
printf("%d\n", strlen(arr));//8.
printf("%d\n", strlen(arr+0));//9.
printf("%d\n", strlen(*arr));//10.
printf("%d\n", strlen(arr[1]));//11.
printf("%d\n", strlen(&arr));//12.
printf("%d\n", strlen(&arr+1));//13.
printf("%d\n", strlen(&arr[0]+1));//14.

在该段代码中我们创建了一个字符数组arr,存放了六个字符。

  1. sizeof(arr):将数组名单独放在了sizeof中,那么就代表计算整个数组的大小,返回值为6。

  2. sizeof(arr+0):arr+0代表数组中首元素的地址,返回值为4/8。

  3. sizeof(* arr):* arr表示对首元素的地址解引用,而arr所指向的是数组中的首元素,即'a'。故返回值为1。

  4. sizeof(arr[1]):arr[1]代表访问数组中第二个元素,它是一个字符,故返回值为1。

  5. sizeof(&arr):&arr表示对整个数组取地址,&arr指向的是整个地址,因此返回值是4/8。

  6. sizeof(&arr+1):&arr+1是一个地址,它指向的是跳过arr数组的地址,返回值为4/8。

  7. sizeof(&arr[0]+1):&arr[0]+1是一个地址,它指向的是数组中第二个元素,故返回值为4/8。
    strlen()是一个库函数,它是用来求取一个字符串的长度,\0是读取字符串的结束标志。返回值是字符串的长度,统计\0以前的字符个数。

  8. strlen(arr):用来求取字符串的长度,但该数组中并没有存放字符串的结束标志\0,因此返回值是一个随机值。

  9. strlen(arr+0):将数组首元素的地址传给strlen,但不知道什么时候会遇到\0,因此返回一个随机值。

  10. strlen(* arr),* arr表示访问数组中第一个元素'a',而strlen接受的参数是指针,strlen会将'a'的ASCII码97当作一个指针,但是这是错误的,因此程序会报错。

  11. strlen(arr[1]):这与十类似,不同的是这次是将字符'b'的ASCII码传给了strlen因此程序会报错。

  12. strlen(&arr):将整个数组的地址传给了strlen,但不知道字符串的结束标志在哪儿,故会返回一个随机值。

  13. strlen(&arr+1):将数组的地址+1跳过该数组,指向数组以外的下一个地址,不知道字符串的结束标志在哪儿,因此返回随机值。

  14. strlen(&arr[0]+1):返回随机值

三、

c 复制代码
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//1.
printf("%d\n", sizeof(arr+0));//2.
printf("%d\n", sizeof(*arr));//3.
printf("%d\n", sizeof(arr[1]));//4.
printf("%d\n", sizeof(&arr));//5.
printf("%d\n", sizeof(&arr+1));//6.
printf("%d\n", sizeof(&arr[0]+1));//7.
printf("%d\n", strlen(arr));//8.
printf("%d\n", strlen(arr+0));//9.
printf("%d\n", strlen(*arr));//10.
printf("%d\n", strlen(arr[1]));//11.
printf("%d\n", strlen(&arr));//12.
printf("%d\n", strlen(&arr+1));//13.
printf("%d\n", strlen(&arr[0]+1));//14.

在该代码中创建了数组arr,存放了7个元素,分别是'a','b','c','d','e','f','\0'。

  1. sizeof(arr):返回值是7。
  2. sizeof(arr+0):arr+0是指向数组中首元素的地址,返回值是4/8。
  3. sizeof(* arr):* arr代表数组首元素'a'返回值为1。
  4. sizeof(arr[1]):arr[1]表示数组中第二个元素'b',返回值是1。
  5. sizeof(&arr):&arr表示整个数组的地址,返回值是4/8。
  6. sizeof(&arr+1):&arr+1表示数组的地址+1是指向数组外的一个地址,返回值为4/8。
  7. sizeof(&arr[0]+1):&arr[0]+1表示数组中第二个元素的地址,返回值是4/8。
  8. strlen(arr):求字符串的长度,统计\0以前的字符个数,返回值为6。
  9. strlen(arr+0):arr+0指向数组中首元素的地址,因此返回值为6。
  10. strlen(* arr): *arr表示数组中首元素'a',它将ASCII码97传给了strlen,这是错误的。
  11. strlen(arr[1]):与上述同理。
  12. strlen(&arr):将数组的地址传给了strlen,返回值是6;
  13. strlen(&arr+1):将给数组指针+1跳过了数组的指针传给了strlen,返回值为随机值
  14. strlen(&arr[0]+1):将数组中第二个元素的地址传给了strlen返回值为5。

四、

c 复制代码
char *p = "abcdef";
printf("%d\n", sizeof(p));//1.
printf("%d\n", sizeof(p+1));//2.
printf("%d\n", sizeof(*p));//3.
printf("%d\n", sizeof(p[0]));//4.
rintf("%d\n", sizeof(&p));//5.
printf("%d\n", sizeof(&p+1));//6.
printf("%d\n", sizeof(&p[0]+1));//7.
printf("%d\n", strlen(p));//8.
printf("%d\n", strlen(p+1));//9.
printf("%d\n", strlen(*p));//10.
printf("%d\n", strlen(p[0]));//11.
printf("%d\n", strlen(&p));//12.
printf("%d\n", strlen(&p+1));//13.
printf("%d\n", strlen(&p[0]+1));//14.

该代码将一个常量字符串的地址传给了p(即字符串首元素的地址);

  1. sizeof§:p是一个地址,故返回值为4/8。
  2. sizeof(p+1):p+1指向字符串中b字符位置 ,p+1是一个地址,故返回值是4/8。
  3. sizeof(* p):*p表示字符串中首个字符'a',故返回值为1。
  4. sizeof(p[0]):p[0] = *(p+0),同上。
  5. sizeof(&p) :&p是一个二级指针,故返回值是4/8。
  6. strlen(&p+1):&p+1是一个地址,故返回值为4/8。
  7. sizeof(&p[0]+1):&p[0]+1是一个指向'b'字符的地址,故返回值是1。
  8. strlen§:求字符串长度,遇到\0停止,返回值为6。
  9. strlen(p+1):将字符串中'b'的地址传给strlen,返回值为5。
  10. strlen(*p):err。
  11. strlen(p[0]):p[0] = *(p+0),故err。
  12. strlen(&p):&p是二级指针,返回值是随机值。
  13. strlen(&p+1):返回值是随机值。
  14. strlen(&p[0]+1):返回值为5。

五、

c 复制代码
//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));//1.
printf("%d\n",sizeof(a[0][0]));//2.
printf("%d\n",sizeof(a[0]));//3.
printf("%d\n",sizeof(a[0]+1));//4.
printf("%d\n",sizeof(*(a[0]+1)));//5.
printf("%d\n",sizeof(a+1));//6.
printf("%d\n",sizeof(*(a+1)));//7.
printf("%d\n",sizeof(&a[0]+1));//8.
printf("%d\n",sizeof(*(&a[0]+1)));//9.
printf("%d\n",sizeof(*a));//10.
printf("%d\n",sizeof(a[3]));//11.

创建了一个3行4列的二维数组。

  1. sizeof(a):计算整个数组的大小,返回值为344 = 48。
  2. sizeof(a[0][0]):a[0][0]代表第一行第一列元素,返回值为4。
  3. sizeof(a[0]):a[0]表示第一行数组名,数组名单独放在sizeof中,计算整个数组的大小,返回值为16。
  4. sizeof(a[0]+1):a[0]没有取地址,没有单独放在sizeof中,表示数组中第一个元素a[0][0]的地址,a[0]+1表示数组中第一行第二个元素的地址。返回值为4/8.
  5. sizeof(*(a[0]+1)): *(a[0]+1) = a[0][1],返回值为4.
  6. sizeof(a+1):a是二维数组名,表示首元素的地址,也就是第一行的地址,a+1表示第二行地址,返回值为4/8.
  7. sizeof(*(a+1)): * (a+1)表示第二行的元素,返回值为16.
  8. sizeof(&a[0]+1):表示第二行元素的地址,返回值为4/8.
  9. sizeof((&a[0]+1)):(&a[0]+1)表示第二行的元素,返回值为16.
  10. sizeof(*a): * a表示第一行元素,返回值为16
  11. sizeof(a[3]):a[3]表示第四行数组名,计算第四行数组的大小,返回值为16。
相关推荐
知困勉行的Allen11 分钟前
MCS-51单片机常用汇编指令和特殊功能寄存器~
c语言·汇编·数据结构·单片机·嵌入式硬件·51单片机·学习方法
破-风3 小时前
leetcode-------mysql
算法·leetcode·职场和发展
WeeJot嵌入式5 小时前
C语言----数组
c语言·数组
叫我阿呆就好了6 小时前
C 实现植物大战僵尸(三)
c语言·开发语言
自不量力的A同学6 小时前
如何利用人工智能算法优化知识分类和标签?
人工智能·算法·分类
CodeJourney.7 小时前
PyTorch不同优化器比较
人工智能·pytorch·算法·能源
winner88817 小时前
对比学习损失函数 - InfoNCE
学习·算法·对比学习·infonce
南宫生8 小时前
力扣-数据结构-12【算法学习day.83】
java·数据结构·学习·算法·leetcode
KeyPan8 小时前
【数据结构与算法:五、树和二叉树】
java·开发语言·数据结构·人工智能·算法·机器学习·计算机视觉
WBingJ8 小时前
机器学习基础-贝叶斯分类器
人工智能·算法·机器学习