C语言指针深入浅出6

目录

  • [1. sizeof 和 strlen 的对比](#1. sizeof 和 strlen 的对比)
    • [1.1 sizeof](#1.1 sizeof)
    • [1.2 strlen](#1.2 strlen)
    • [1.3 sizeof 和 strlen 的对比](#1.3 sizeof 和 strlen 的对比)
  • 2.数组和指针笔试题解析
    • [2.1 一维数组](#2.1 一维数组)
    • [2.2 字符数组](#2.2 字符数组)
    • [2.3 二维数组](#2.3 二维数组)
  • [3. 指针运算笔试题解析](#3. 指针运算笔试题解析)
    • [3.1 **题目1**:](#3.1 题目1:)
    • [3.2 **题目2**:](#3.2 题目2:)
    • [3.3 题目3](#3.3 题目3)
    • [3.4 **题目4**:](#3.4 题目4:)
    • [3.5 **题目5**:](#3.5 题目5:)
    • [3.6 题目6:](#3.6 题目6:)
    • [3.7 题目7:](#3.7 题目7:)

1. sizeof 和 strlen 的对比

1.1 sizeof

在学习C语言数据类型和变量时,我们学习了sizeof操作符,sizeof 是用来计算变量或数据类型所占内存大小的操作符,单位是字节。sizeof的返回值是size_t类型的,它只关心占用空间,不关心内存中存放的具体数据。

比如:

c 复制代码
int main()
{
	int n = 40;
	int a = 0;
	printf("%zu\n", sizeof(n));  //4
	printf("%zu\n", sizeof(40)); //4
	printf("%zu\n", sizeof n);   //4
	printf("%zu\n", sizeof(a = n + 10)); //sizeof中表达式不计算,计算结果为4
	printf("%d\n", a); //0
	return 0;
}

1.2 strlen

strlen 是C语⾔库函数 ,功能是求字符串⻓度。函数原型如下:

c 复制代码
size_t strlen ( const char * str );

str:要统计的字符串地址。
strlen:从 str 指向的位置开始统计字符个数。

遇到 \0 停止:不统计 \0 本身。

返回值 size_t:表示字符串中有效字符的个数。
注意:strlen 是库函数,不是操作符,所以,使用strlen库函数要包含头文件<string.h>

c 复制代码
#include <string.h> //使用strlen库函数时要包含头文件
#include <stdio.h>
int main()
{
	char arr1[3] = { 'a', 'b', 'c' };
	char arr2[] = "abc";
	printf("%d\n", strlen(arr1)); // arr1 中没有 '\0',strlen 会继续向后查找,可能越界访问,结果未定义
	printf("%d\n", strlen(arr2)); //3
	printf("%d\n", sizeof(arr1)); //3
	//arr1是字符数组,存储了'a' , 'b' , 'c' 三个字符
	printf("%d\n", sizeof(arr2));//4 
	// arr2 存储 'a','b','c','\0',占 4 个字节
	return 0; 
}

1.3 sizeof 和 strlen 的对比

对比项 sizeof strlen
本质 操作符 库函数
头文件 不需要额外头文件 需要包含头文件 <string.h>
作用 计算变量或类型占用的内存大小 计算字符串的长度
统计内容 统计所占内存的字节数 统计 \0 之前字符的个数
单位 字节 字符个数
是否关注内容 不关心内存中存放什么数据 需要查找字符串结束标志 \0
注意事项 结果由变量或类型本身决定 如果没有 \0,可能会越界查找

2.数组和指针笔试题解析

讲解之前我们需要知道数组名的意义 ,数组名的意义在C语言指针深入浅出3中讲解到了,我把最核心的知识挪到这里:

  1. sizeof(数组名),这⾥的数组名表⽰整个数组 ,计算的是整个数组的⼤⼩。
  2. &数组名,这⾥的数组名表⽰整个数组 ,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表⽰⾸元素的地址。

2.1 一维数组

c 复制代码
#include <stdio.h>
int main()
{
    int a[] = { 1, 2, 3, 4 };
    printf("%zu\n", sizeof(a));          
    printf("%zu\n", sizeof(a + 0));      
    printf("%zu\n", sizeof(*a));        
    printf("%zu\n", sizeof(a + 1));     
    printf("%zu\n", sizeof(a[1]));     
    printf("%zu\n", sizeof(&a));         
    printf("%zu\n", sizeof(*&a));     
    printf("%zu\n", sizeof(&a + 1));     
    printf("%zu\n", sizeof(&a[0]));      
    printf("%zu\n", sizeof(&a[0] + 1));  
    return 0;
}



2.2 字符数组

代码1:

c 复制代码
#include <stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%zu\n", sizeof(arr)); 
	printf("%zu\n", sizeof(arr + 0));
	printf("%zu\n", sizeof(*arr));
	printf("%zu\n", sizeof(arr[1]));
	printf("%zu\n", sizeof(&arr));
	printf("%zu\n", sizeof(&arr + 1));
	printf("%zu\n", sizeof(&arr[0] + 1));
	return 0;
}


代码2:

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    printf("%zu\n", strlen(arr));          
    printf("%zu\n", strlen(arr + 0));      
    printf("%zu\n", strlen(*arr));          
    printf("%zu\n", strlen(arr[1]));        
    printf("%zu\n", strlen(&arr));          
    printf("%zu\n", strlen(&arr + 1));     
    printf("%zu\n", strlen(&arr[0] + 1));  
    return 0;
}


代码3:

c 复制代码
#include <stdio.h>
int main()
{
	char arr[] = "abcdef";
	printf("%zu\n", sizeof(arr));         
	printf("%zu\n", sizeof(arr + 0));       
	printf("%zu\n", sizeof(*arr));          
	printf("%zu\n", sizeof(arr[1]));        
	printf("%zu\n", sizeof(&arr));          
	printf("%zu\n", sizeof(&arr + 1));      
	printf("%zu\n", sizeof(&arr[0] + 1));   
	return 0;
}


代码4:

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = "abcdef";
    printf("%zu\n", strlen(arr));           
    printf("%zu\n", strlen(arr + 0));      
    printf("%zu\n", strlen(*arr));          
    printf("%zu\n", strlen(arr[1]));       
    printf("%zu\n", strlen(&arr));         
    printf("%zu\n", strlen(&arr + 1));    
    printf("%zu\n", strlen(&arr[0] + 1));  
    return 0;
}


代码5:

c 复制代码
#include <stdio.h>

int main()
{
    char* p = "abcdef";
    printf("%zu\n", sizeof(p));        
    printf("%zu\n", sizeof(p + 1));    
    printf("%zu\n", sizeof(*p));      
    printf("%zu\n", sizeof(p[0]));     
    printf("%zu\n", sizeof(&p));        
    printf("%zu\n", sizeof(&p + 1));   
    printf("%zu\n", sizeof(&p[0] + 1)); 
    return 0;
}


代码6:

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    const char* p = "abcdef";
    printf("%zu\n", strlen(p));          
    printf("%zu\n", strlen(p + 1));      
    printf("%zu\n", strlen(*p));        
    printf("%zu\n", strlen(p[0]));       
    printf("%zu\n", strlen(&p));         
    printf("%zu\n", strlen(&p + 1));    
    printf("%zu\n", strlen(&p[0] + 1));  
    return 0;
}



2.3 二维数组

c 复制代码
#include <stdio.h>
int main()
{
int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));
return 0;
}

3. 指针运算笔试题解析

3.1 题目1:

c 复制代码
#include <stdio.h>
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1); 
	printf("%d,%d", *(a + 1), *(ptr - 1)); 
	return 0;
}



3.2 题目2:

这个题目的是指针的+ -运算,相关知识点:C语言指针深入浅出1。
注意:注意:%p 用于打印指针地址,通常以十六进制形式显示;在 VS 的 x86 环境下,一般显示为 8 位十六进制,不足位会补 0。

c 复制代码
#include <stdio.h>

//在X86环境下 1
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}* p = (struct Test*)0x100000;

int main()
{
	printf("%p\n", p + 0x1); 
	printf("%p\n", (unsigned long)p + 0x1); 
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}



3.3 题目3

这道题用到了逗号表达式 ,相关知识点:C语言操作符详解。

c 复制代码
#include <stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) }; 
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}



3.4 题目4:

c 复制代码
#include <stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}


我再来讲解一下FFFFFFFC怎么来的:

相关知识点:C语言操作符详解。

在 VS 的 x86 环境下,-4 用 32 位补码表示:

c 复制代码
-4 的二进制:
10000000 00000000 00000000 00000100
取反(符号位不变,其他位按位取反):
11111111 11111111 11111111 11111011
加 1:
11111111 11111111 11111111 11111100

把最后一行按 4 位一组转成十六进制:

c 复制代码
1111 1111 1111 1111 1111 1111 1111 1100
  F    F    F    F    F    F    F    C

-4 的 32 位补码 = 0xFFFFFFFC。


3.5 题目5:

c 复制代码
#include <stdio.h>
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	int* ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}



3.6 题目6:

c 复制代码
#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}



3.7 题目7:

c 复制代码
#include <stdio.h>
int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char* * cp[] = { c + 3,c + 2,c + 1,c };
	char** * cpp = cp;
	printf("%s\n", **++cpp); 
	printf("%s\n", *-- * ++cpp + 3);
	printf("%s\n", *cpp[-2] + 3);
	printf("%s\n", cpp[-1][-1] + 1);
	return 0;
}

完

相关推荐
专注仿真2 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes3 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
代码不停3 小时前
自动化测试(java)
java·开发语言·selenium·自动化
鬼手点金5 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
爱上网的小舟5 小时前
星际战士2启动错误怎么办?5种游戏报错解决方法
开发语言·php
阿里嘎多学长6 小时前
2026-10-12 GitHub 热点项目精选
开发语言·程序员·github·代码托管
wangchunyu1147 小时前
Python 数据可视化实战入门教程
开发语言·python·信息可视化
wuyk5558 小时前
嵌入式驱动开发:量产级工程化实战(第9篇)——低功耗下的通信可靠性
c语言·驱动开发·stm32·单片机·嵌入式硬件
学逆向的8 小时前
C 突破编译器限制
c语言·开发语言·网络安全
jimy19 小时前
C++ 虚函数表:基类和派生类共用一张 vtable 吗?
开发语言·c++