当前位置: 首页 > article >正文

(C语言)sizeof与strlen的区别,以及有关习题练习

一·sizeof与strlen的区别

在C语言中sizeofstrlen是两个常用的工具,但它们的功能和使用场景有所不同。以下是基于我搜索到的资料对这两个概念的详细解析:

1. 定义与作用
  • sizeof:

    • sizeof是一个操作符,用于计算变量或类型所占的内存字节数。
    • 它可以应用于任何类型的数据,包括基本数据类型、数组、结构体等。
    • sizeof在编译时计算其值,因此可以用于定义数组维数等。
    • 返回值类型为size_t,通常在头文件stddef.h中定义。
  • strlen:

    • strlen是一个函数,用于计算以空字符\0结尾的字符串中的字符个数。
    • 不包括字符串末尾的\0字符。
    • strlen在运行时计算其值,因此需要包含string.h头文件。
    • 参数必须是字符型指针(char*),且必须是以\0结尾的字符串。
2. 参数类型
  • sizeof:

    • 适用于所有数据类型:基本类型(intchar 等)、数组、结构体、指针等。
    • 例如:sizeof(int)sizeof(a),其中a是一个变量。(ps:这个括号可以省略掉 如 a)
    • #include <stdio.h>
      int main()
      {
      	int a = 22;
      	printf("%zd\n", sizeof a);
      	printf("%zd\n", sizeof (a));
      	printf("%zd\n", sizeof(int ));
      	//printf("%zd\n", sizeof int);
      	return 0;
      }

  • strlen:

    • 仅适用于以 \0 结尾的字符串(字符数组或字符指针)。

      参数必须是字符型指针(char*),且必须是以\0结尾的字符串。(用于获取字符串的实际长度直到遇到 \0 为止,且不包含 \0)。)
    • 例如:strlen("Hello, world!")

3. 对字符串的处理

  • sizeof
    计算字符串的总内存大小(包括末尾的 \0)。
    例如:

    char str[] = "hello";
    printf("%zu\n", sizeof(str));  // 输出 6(5个字符 + 1个 '\0')
  • strlen
    计算字符串的实际字符数(不包括 \0)。
    例如:

char str[] = "hello";
printf("%zu\n", strlen(str));  // 输出 5
 

总结
  • sizeof是一个操作符,用于计算变量或类型所占的内存字节数,适用于任何类型的数据。
  • strlen是一个函数,用于计算以空字符\0结尾的字符串中的字符个数,不包括\0字符。
  • sizeof在编译时计算其值,而strlen在运行时计算其值。
  • sizeof的参数可以是类型名或变量名,而strlen的参数必须是字符型指针,并且必须是以\0结尾的字符串。

 二·数组名的理解

1. 数组名的本质

  • 数组名是数组首元素的地址(即 &array[0]),但在某些情况下会表现出不同的行为。

  • 数组名本身不是指针变量,而是一个符号常量,代表数组的起始地址。


2. 数组名的两种关键行为

(1) 作为首元素地址
  • 在大多数表达式中,数组名会被隐式转换为指向数组首元素的指针(类型为 element_type*)。

    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr;  // arr 退化为 &arr[0]
(2) 作为整个数组的标识符
  • 在以下两种情况下,数组名不会被退化为指针,而是表示整个数组:

    1. sizeof(arr):计算的是整个数组占用的字节数。

      int arr[5];
      printf("%zu\n", sizeof(arr));  // 输出 20(假设 int 为 4 字节)

    2. &arr:取数组的地址,类型为 int (*)[5](指向整个数组的指针)。

       
int arr[5];
int (*ptr_to_array)[5] = &arr;  // 类型是 int(*)[5]
 

总结

  • 数组名是首元素地址,但在 sizeof 和 & 操作中代表整个数组。

  • 数组名不是指针变量,而是一个固定的符号常量。

三·习题练习 

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%zd\n", sizeof(a));     //sizeof(数组名), 4*4 = 16
	printf("%zd\n", sizeof(a + 0)); //a就是首元素的地址,a+0还是首元素的地址,计算的是地址的大小: 4/ 8
	printf("%zd\n", sizeof(*a));    //a就是首元素的地址,*a就是首元素.计算的是首元素的大小:4个字节
	printf("%zd\n", sizeof(a + 1)); //a就是首元素的地址,a+1是第二个元素的地址,计算的是地址的大小: 4 / 8
	printf("%zd\n", sizeof(a[1])); //计算的是第二个元素的大小,4
	printf("%zd\n", sizeof(&a));//&a - 取出的是数组的地址. 是地址都是4或8个字节
	//&a + 1 跳过多少个字节: 16
	//*&a 这里的解引用访问到16个字节
	//int (*)[4]
	printf("%zd\n", sizeof(*&a)); //16
	//解释1*&a, * 和 &抵消了,等于sizeof(a) 
// 解释2 先&a取到a的地址 再*解用用 [1],[2],[3],[4]
    printf("%zd\n", sizeof(a)); //16
	printf("%zd\n", sizeof(&a + 1));   //&a+1是跳过整个数组,指向4的后面,其实也是地址,是地址就是4 / 8个字节
	printf("%zd\n", sizeof(&a[0]));   //&a[0]就是首元素,4 8 个字节
	printf("%zd\n", sizeof(&a[0] + 1)); //&a[0] + 1是第二个元素的地址. 8
	return 0;
}

 

注意 现在的情况是在64 的环境下运行 如果在86的环境下 地址字节为8

难点解释:

printf("%zd\n", sizeof(*&a)); //16
 //  解释1   *&a, * 和 &抵消了,等于sizeof(a) 
//   解释2    先&a取到a的地址 再*解运用 计算a的数组  [1],[2],[3],[4] 

printf("%zd\n", sizeof(&a + 1));

  //&a+1是跳过整个数组,指向4的后面,其实也是地址,是地址就是4 / 8个字节 

从零开始,步步为营

不要害怕C语言的复杂性,每个人都是从零开始的。只要你坚持学习,每天进步一点点,终会看到自己的成长。

每日都会分享习题练习,加油练起来吧!!!

下篇分享一些可以练习习题的网站

关注一手呗

 


http://www.kler.cn/a/595117.html

相关文章:

  • YOLO可视化界面,目标检测前端QT页面。
  • 深度解析超线程技术:一核多用的奥秘
  • 深入理解MySQL中的MVCC机制
  • 使用Qdrant等其他向量数据库时需要将将numpy 数组转换为列表 确保数据能被正确处理和序列化,避免类型不兼容的问题。
  • 正则表达式:文本处理的瑞士军刀
  • 动态生成 CSS 工具类:CSS函数实现 `pad20-top`、`pad40-bottom` 等灵活样式
  • tailwindcss如何修改elementplus的内部样式
  • 深度学习与传统算法在人脸识别领域的演进:从Eigenfaces到ArcFace
  • JsonAutoDetect.Visibility
  • Camera2 API拍照失败问题实录:从错误码到格式转换的排坑之旅
  • Langchain 提示词(Prompt)
  • 解锁C++编程能力:基础语法解析
  • DeepSeek面试——模型架构和主要创新点
  • 如何在Linux环境下编译文件
  • 【群晖NAS】git常见问题解决方法
  • NIO入门
  • VSCode中搜索插件显示“提取扩展时出错。Failed to fetch”问题解决!
  • 平安信托张中朝:养老信托将助力破解“中国式养老”难题
  • 数智读书笔记系列021《大数据医疗》:探索医疗行业的智能变革
  • CUDA编程面试高频30题