【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)

简介: 【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)

思路大纲:

1.sizeof和strlen的对比

但是需要强调一下哈:两者的返回类型都是size_t类型的,两个无符号类型的整型数字相减,在数学上得到的答案是一个负数,在计算机上是一个很大的正数,因为对于计算机而言无符号整形不存在负数。

2.数组和指针笔试题(借用sizeof与strlen进行体会)

编号1:

int main()
{
  int a[] = { 1,2,3,4 };
  printf("%d\n", sizeof(a));//16,         计算的是整个数组的内存大小
  printf("%d\n", sizeof(a + 0));// 4/8     a是数组名,代表首元素的地址,+0操作之后还是数组首元素地址
  printf("%d\n", sizeof(*a));//4           *a,对数组名(数组首元素地址)进行解引用操作,拿到的是数字1
  printf("%d\n", sizeof(a + 1));//4/8      a是数组名,代表数组首元素地址,+1操作之后拿到的是数组第二个元素的地址
  printf("%d\n", sizeof(a[1]));//4         a[1]==*(a+1),拿到的是数组第二个元素
  printf("%d\n", sizeof(&a));//4/8         取地址,是一个地址,是整个数组的地址
  printf("%d\n", sizeof(*&a));//16         *与&抵消了
  printf("%d\n", sizeof(&a + 1));//4/8     是地址
  printf("%d\n", sizeof(&a[0]));//4/8      是数组第一个元素的地址
  printf("%d\n", sizeof(&a[0] + 1));//4/8  是数组第二个元素的地址
  return 0;
}

编号2:

char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6           sizeof(数组名),计算的整个数组的大小
printf("%d\n", sizeof(arr + 0));//4/8     arr是数组首元素的地址,+0操作之后仍然是数组首元素的地址,
printf("%d\n", sizeof(*arr));//1          arr是数组首元素地址,解引用操作,得到的是数组第一个元素,其内存大小为1
printf("%d\n", sizeof(arr[1]));//1        arr[1]==*(arr+1)得到的是数组第二个元素,其类型为char类型,内存大小为1
printf("%d\n", sizeof(&arr));//4/8        这是整个数组的地址
printf("%d\n", sizeof(&arr + 1));//4/8    某个地址
printf("%d\n", sizeof(&arr[0] + 1));//4/8 地址

编号3:

char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//未知数      strlen函数以/0为结束标志,该字符数组中没有添加/0,后面内存某个位置有/0
printf("%d\n", strlen(arr + 0));//未知数  strlen函数以/0为结束标志,该字符数组中没有添加/0,后面内存某个位置有/0
//printf("%d\n", strlen(*arr));//error      strlen函数的参数需要给一个地址,arr是数组首元素的地址,但是*a得到的是字符‘a’,也就是strlen把97当作一个地址吗?这种写法是错误的
//printf("%d\n", strlen(arr[1]));//error    strlen函数的参数需要一个地址,而不是一个字符
printf("%d\n", strlen(&arr));//未知数     
printf("%d\n", strlen(&arr + 1));//未知数-6
printf("%d\n", strlen(&arr[0] + 1));//未知数-1

编号4:

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7           sizeof计算的是数组所占内存大小,“字符串”这种写法,编译器默认后面有个\0
printf("%d\n", sizeof(arr + 0));//4/8     arr是一个数组名,是一个地址,+0操作之后还是那个地址而已
printf("%d\n", sizeof(*arr));//1          arr是数组首元素的地址,解引用操作之后,得到的是字符a,其所占内存大小为1
printf("%d\n", sizeof(arr[1]));//1        数组第二个元素所占内存大小,其所占内存大小为1
printf("%d\n", sizeof(&arr));//4/8        内存
printf("%d\n", sizeof(&arr + 1));//4/8    内存
printf("%d\n", sizeof(&arr[0] + 1));//4/8 内存

编号5:

int main()
{
  char arr[] = "abcdef";//表面上看是6个字符,实际上arr数组是七个字符的字符串,后面还有一个\0
  
  printf("%d\n", strlen(arr));//6           strlen函数计算的是/0之前字符个数 
  printf("%d\n", strlen(arr + 0));//6       strlen函数需要传入的是一个指针,跟第一个没啥区别
  //printf("%d\n", strlen(*arr));//error      strlen函数需要一个地址,但是解引用数组名,拿到的是字符a,也就是97,可能会把97当作一个地址来进行使用。
  //printf("%d\n", strlen(arr[1]));//error    strlen函数需要传入地址,而不是拿到arr数组中的某个值
  printf("%d\n", strlen(&arr));//6          传入的是整个数组的地址,但是这个整个数组的地址跟arr是一样的
  printf("%d\n", strlen(&arr + 1));//未知数 &arr拿到的是整个数组的地址,+1操作之后,跳过的是一个char(*)[7]的一个指针类型,会直接跳过整个数组
  printf("%d\n", strlen(&arr[0] + 1));//5   拿到数组首元素地址再加一操作,得到的是数组第二个元素的地址,6-1=5
  return 0;
}

编号6:

char* p = "abcdef";//                     这是一个指向常量字符串的指针 
printf("%d\n", sizeof(p));//4/8           p是一个指向常量字符串的指针,其大小取决与编译环境,如果是x86,是四个字节;如果是x64的话,是8个字节
printf("%d\n", sizeof(p + 1));//4/8       p+1也是一个指针
printf("%d\n", sizeof(*p));//1            *p找到的是字符a,其所占的内存大小为1字节
printf("%d\n", sizeof(p[0]));//1          p[0]==*(p+0),所以说跟上面那个没什么差别
printf("%d\n", sizeof(&p));//4/8          这是一个指针,char**类型的指针
printf("%d\n", sizeof(&p + 1));//4/8      与上面同理
printf("%d\n", sizeof(&p[0] + 1));//4/8   这是一个地址(指针)

编号7:

char* p = "abcdef";
printf("%d\n", strlen(p));//6              strlen函数以找\0为结束标志,strlen函数需要一个地址参数
printf("%d\n", strlen(p + 1));//5          p+1指向的是字符b
//printf("%d\n", strlen(*p));//error         拿到的是一个字符,并不是地址
//printf("%d\n", strlen(p[0]));//error       拿到的不是一个地址
printf("%d\n", strlen(&p));//未知          拿到的是地址,但不是字符串地址,因而不能确定
printf("%d\n", strlen(&p + 1));//未知      拿到的是地址,但不是字符串的地址,不确定
printf("%d\n", strlen(&p[0] + 1));//5      拿到数组第二个元素地址

编号8:

int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48             sizeof(数组名),得到的是整个数组大小所占内存空间
printf("%d\n", sizeof(a[0][0]));//4        a[0][0]拿到的是数组第一个元素地址
printf("%d\n", sizeof(a[0]));//16          a[0]拿到的是二维数组的第一行,当然这里理解需要结合二维数组本质去理解
printf("%d\n", sizeof(a[0] + 1));//4/8     因为a[0]是一个地址,+1之后仍然是一个地址
printf("%d\n", sizeof(*(a[0] + 1)));//4    解引用拿到一个具体的元素数值
printf("%d\n", sizeof(a + 1));//4/8        地址
printf("%d\n", sizeof(*(a + 1)));//16      拿到整个第二行
printf("%d\n", sizeof(&a[0] + 1));//4/8    地址
printf("%d\n", sizeof(*(&a[0] + 1)));//16  拿到整个第二行地址,在进行解引用操作
printf("%d\n", sizeof(*a));//16            拿到的是整个第一行,4*4=12
printf("%d\n", sizeof(a[3]));//16          这里不存在越界,因为sizeof不关注内存中存放的内容

3.指针运算笔试题

转链接:指针运算笔试题

相关文章
|
3月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
63 0
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
86 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
55 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
45 7
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
159 13
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
135 3
|
2月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
63 11
|
2月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
2月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
44 1