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 环境下,-432 位补码表示:

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;
}

相关推荐
知识分享小能手1 小时前
R语言入门学习教程,从入门到精通,R语言数据处理与清洗 (9)
开发语言·学习·r语言
号码认证服务1 小时前
如何让来电显示公司名代替陌生数字号码?企业号码认证开通指南
服务器·c语言·网络·经验分享·智能手机·云计算·php
计算机安禾1 小时前
【c++面向对象编程】第19篇:多继承与菱形继承(二):虚拟继承的内存模型与复杂性
开发语言·c++
思麟呀1 小时前
在C++基础上理解CSharp-1
开发语言·c++·c#
一念春风2 小时前
QwenPaw(替代小龙虾)大模型
开发语言·php
小短腿的代码世界2 小时前
Qt状态机框架深度解析:从状态图到事件驱动闭环
开发语言·qt
广州灵眸科技有限公司2 小时前
瑞芯微(EASY EAI)RV1126B 模型部署API说明
linux·开发语言·网络·人工智能·深度学习·算法·yolo
東隅已逝,桑榆非晚2 小时前
深⼊理解指针(5)
c语言·笔记·算法
计算机安禾2 小时前
【c++面向对象编程】第20篇:override与final关键字:现代C++对继承的控制
开发语言·c++