C语言:复习

文章目录

  • 思维导图
  • 数组和指针
  • 库函数的模拟实现
  • 判断大小端

最近知识学的差不多了,因此开始复习,本篇开始的是对于C语言的复习

思维导图

下面就依据下图,进行内容的整理

在这里插入图片描述

在这里插入图片描述

数组和指针

这个模块算是C语言中比较大的一个模块了,具体概念就不多说了,直接用例题

数组

#include <stdio.h>

int main()
{
	//一维数组
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));    // 16
	printf("%d\n", sizeof(a + 0)); // 4/8
	printf("%d\n", sizeof(*a));    // 4
	printf("%d\n", sizeof(a + 1)); // 4/8
	printf("%d\n", sizeof(a[1]));  // 4
	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

	//字符数组
	char arr[] = { 'a','b','c','d','e','f', '\0'};
	printf("%d\n", sizeof(arr));       // 6
	printf("%d\n", sizeof(arr + 0));   // 4/8
	printf("%d\n", sizeof(*arr));      // 1
	printf("%d\n", sizeof(arr[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
	printf("%d\n", strlen(arr));   // 6
	printf("%d\n", strlen(arr + 0));// 6
	//printf("%d\n", strlen((const char*) * arr)); // ? 
	//printf("%d\n", strlen((const char*)arr[1])); // ?
	printf("%d\n", strlen((const char*)&arr)); // 6
	printf("%d\n", strlen((const char*)(&arr + 1)));  // 未定义
	printf("%d\n", strlen((const char*)(&arr[0] + 1))); // 5

	return 0;
}

指针

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);  // 指向最后一个元素的下一个位置
	printf("%d,%d", *(a + 1), *(ptr - 1));  // a[1] 和 a[4]
	return 0;
}
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

接下来分析 main() 函数中的 printf 表达式:

  1. printf("%p\n", p + 0x1);
    

    在这里,p 是一个指向 struct Test 的指针,对其进行加 0x1 操作意味着指针向前偏移 0x1struct Test 类型的大小,即偏移 20 字节。因此,p + 0x1 的值为 0x100014%p 格式说明符用于打印指针的值,所以这行代码输出 0x100014

  2. printf("%p\n", (unsigned long)p + 0x1);
    

    首先,将指针 p 强制转换为 unsigned long 类型。虽然 p 的原始类型是一个指针,但转换为 unsigned long 后,它被视为一个数值。然后对这个数值加上 0x1,即 0x100000 + 0x1 = 0x100001。接着,将结果作为指针传递给 printf 函数,使用 %p 格式说明符打印。理论上,这行代码的行为是未定义的,因为 0x100001 不是一个有效的指针值。实际运行时可能会导致程序崩溃或其他不可预期的结果。

  3. printf("%p\n", (unsigned int*)p + 0x1);
    

    这里,将指针 p 强制转换为 unsigned int* 类型,即指向无符号整型的指针。由于 struct Test 大小为 20 字节,而通常情况下 unsigned int 类型为 4 字节(具体字节数可能因编译器和平台而异),所以 p 指向的对象大小与 unsigned int* 类型指针所期望的对象大小不匹配。接着,对转换后的指针加上 0x1,即偏移 4 字节。最后,将结果作为指针传递给 printf 函数,使用 %p 格式说明符打印。这行代码同样存在未定义行为,因为指针类型转换后与原始对象大小不匹配,后续操作可能导致程序崩溃或其他不可预期的结果。

综上所述:

  • 第一个 printf 表达式输出 0x100014,这是正确地对 struct Test 类型指针进行偏移后的结果。
  • 第二个和第三个 printf 表达式涉及不恰当的指针类型转换和指针运算,其行为是未定义的,可能会导致程序崩溃或其他不可预期的结果。在实际编程中应避免这类操作。
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	// 1000 0000 0000 0000 0000 0000 0000 0000 
	// 0100 0000 0000 0000 0000 0000 0000 0000
	// 00        00        00        02
	// 0000 0000 0000 0000 0000 0000 0000 0100
	int* ptr1 = (int*)(&a + 1); // 最后一个元素的下一个位置
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2); // 最后一个元素
	return 0;
}
#include <stdio.h>

int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]); // p + 0 实际存储的是1 3 5 0 0 ...
	return 0;
}

#include <stdio.h>
int main()
{
	// 1, 2, 3, 4, 5
	// 6, 7, 8, 9, 10
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1); // 跳过了整个二维数组
	int* ptr2 = (int*)(*(aa + 1)); // aa[1]
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1)); // 10 5
	return 0;
}
#include <stdio.h>
int main()
{
	const char* a[] = { "work","at","alibaba" };
	const char** pa = a; // w
	pa++; // at
	printf("%s\n", *pa);
	return 0;
}

库函数的模拟实现

void* mymemcpy(void* destination, const void* source, size_t num)
{
	void* res = destination;
	assert(destination);
	assert(source);
	while (num--)
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
	return res;
}
void* mymemmove(void* destination, const void* source, size_t num)
{
	void* res = destination;
	assert(destination);
	assert(source);
	if (destination <= source || (char*)destination >= ((char*)source) + num)
	{
		destination = (char*)destination + num - 1;
		source = (char*)source + num - 1;
		while (num--)
		{
			*(char*)destination = *(char*)source;
			destination = (char*)destination - 1;
			source = (char*)source - 1;
		}
	}
	else
	{
		while (num--)
		{
			*(char*)destination = *(char*)source;
			destination = (char*)destination + 1;
			source = (char*)source + 1;
		}
	}
	return res;
}

判断大小端

union MyUnion
{
	int a;
	char c[4];
};
int main()
{
	MyUnion un;
	un.a = 0x123456;
	if (un.c[0] == 0x12)
		printf("大端\n");
	else
		printf("小端\n");
	return 0;
}

int main()
{
	int a = 0x123456;
	char* pa = (char*)&a;
	if (*pa == 0x12)
		printf("大端\n");
	else
		printf("小端\n");
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/574019.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Three.js——基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

如何使用rdtsc和C/C++来测量运行时间(如何使用内联汇编和获取CPU的TSC时钟频率)

本文主要是一个实验和思维扩展&#xff0c;是一个初步的尝试&#xff0c;旨在研究一些时间测量实现和在 C/C 中内联汇编和汇编函数的使用方法。除非你有特殊用途&#xff0c;不然不要使用汇编指令来实现这个功能。在“扩展阅读”部分会列出了一些不需要内联汇编实现的方法。 写…

猫头虎分享已解决Bug || TypeError: Cannot read property ‘map‘ of undefined**

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

4.25 C高级

思维导图 作业 2.输入两个数&#xff0c;实现两个数的排序 3.输入一个数&#xff0c;计算是否是水仙花 if ((g*g*gs*s*sb*b*bnum)) then echo YES else echo no fi 4.输入一个成绩实现登记判断 90-100A 80-89B 70-79C 60-69D 0-59E

“追忆似水年华 展望美好未来”——生命故事小组忆童趣活动

在人生的长河中&#xff0c;童年是明亮色彩的日子&#xff0c;但随着岁月的流逝&#xff0c;这些回忆有时会变得模糊&#xff0c;为唤起他们对美好童年的回忆&#xff0c;2024年4月9日上午9点&#xff0c;由成都市社会组织社区和社工人才服务中心支持&#xff0c;新都区民政局指…

OpenHarmony语言基础类库【@ohos.util.HashMap (非线性容器HashMap)】

HashMap底层使用数组链表红黑树的方式实现&#xff0c;查询、插入和删除的效率都很高。HashMap存储内容基于key-value的键值对映射&#xff0c;不能有重复的key&#xff0c;且一个key只能对应一个value。 HashMap和[TreeMap]相比&#xff0c;HashMap依据键的hashCode存取数据&…

文旅元宇宙解决方案|人工智能、虚拟数字人、导览系统深度应用

随着数字技术的飞速发展&#xff0c;文旅行业正迎来一场前所未有的变革。道可云文旅元宇宙平台以其前瞻性的技术视野和创新的解决方案&#xff0c;为各级文旅主管部门、旅游景区、博物馆、艺术展览馆等单位提供了全新的智慧景区导览、元宇宙场景搭建、AR场景开发以及数字人导游…

市场上免费且高效的云渲染平台,渲染100邀请码7788

在当今数字化时代&#xff0c;云渲染服务因其便捷性和高效性而日益受到追捧&#xff0c;广泛应用于建筑设计、影视制作和视觉艺术等多个领域。它不仅能够显著缩短项目完成的时间&#xff0c;还能大幅提升工作效率。 接下来&#xff0c;我们将探讨一些市场上公认的优质且免费的…

【Qt常用控件】—— QWidget 核心属性

目录 &#xff08;一&#xff09;控件概述 1.1 关于控件体系的发展 &#xff08;二&#xff09;QWidget 核心属性 2.1 核心属性概览 2.2 enabled 2.3 geometry 2.4 windowTitle 2.5 windowIcon 2.6 windowOpacity 2.7 cursor 2.8 font 2.9 toolTip 2.10 focus…

数据结构四:线性表之带头结点的单向循环循环链表的设计

前面两篇介绍了线性表的顺序和链式存储结构&#xff0c;其中链式存储结构为单向链表&#xff08;即一个方向的有限长度、不循环的链表&#xff09;&#xff0c;对于单链表&#xff0c;由于每个节点只存储了向后的结点的地址&#xff0c;到了尾巴结点就停止了向后链的操作。也就…

MySQL统计一个表的行数,使用count(1), count(字段), 还是count(*)?

为什么要使用count函数&#xff1f; 在开发系统的时候&#xff0c;我们经常要计算一个表的行数。比如我最近开发的牛客社区系统&#xff0c;有一个帖子表&#xff0c;其中一个功能就是要统计帖子的数量&#xff0c;便于分页显示计算总页数。 CREATE TABLE discuss_post (id i…

展览模型一般怎么打灯vray---模大狮模型网

在展览模型的设计中&#xff0c;灯光的运用是至关重要的&#xff0c;它不仅能够增强展品的视觉效果&#xff0c;还可以营造出独特的氛围和情感。在利用V-Ray进行灯光设置时&#xff0c;有一些常用的技巧和方法可以帮助设计师实现理想的展览效果。在本文中&#xff0c;我们将介绍…

漏洞修复优先级考虑-不错的思路

权威说法&#xff1a; 漏洞利用预测评分系统 &#xff08;EPSS&#xff09; 是一项数据驱动的工作&#xff0c;用于估计软件漏洞在野外被利用的可能性&#xff08;概率&#xff09; https://www.first.org/epss/ GitHub - TURROKS/CVE_Prioritizer: Streamline vulnerability…

在windows上安装MySQL数据库全过程

1.首先在MySQL的官网找到其安装包 在下图中点击MySQL Community(gpl) 找到MySQL Community Server 选择版本进行安装包的下载 2.安装包&#xff08;Windows (x86, 64-bit), MSI Installer&#xff09;安装步骤 继续点击下一步 继续进行下一步&#xff0c;直到出现此界面&#…

基于小程序实现的惠农小店系统设计与开发

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

leetcode-比较版本号-88

题目要求 思路 1.因为字符串比较大小不方便&#xff0c;并且因为需要去掉前导的0&#xff0c;这个0我们并不知道有几个&#xff0c;将字符串转换为数字刚好能避免。 2.当判断到符号位的时候加加&#xff0c;跳过符号位。 3.判断数字大小&#xff0c;来决定版本号大小 4.核心代…

探索直播+电商系统中台架构:连接消费者与商品的智能纽带

随着直播电商的崛起&#xff0c;电商行业进入了全新的智能时代。直播形式的互动性和即时性为消费者提供了全新的购物体验&#xff0c;而电商平台则为商品的展示、销售和配送提供了强大的支持。在这一背景下&#xff0c;直播电商系统中台架构成为了连接消费者与商品的智能纽带&a…

ABTest如何计算最小样本量-工具篇

如果是比例类指标&#xff0c;有一个可以快速计算最小样本量的工具&#xff1a; https://www.evanmiller.org/ab-testing/sample-size.html 计算样本量有4个要输入的参数&#xff1a;①一类错误概率&#xff0c;②二类错误概率 &#xff08;一般是取固定取值&#xff09;&…

【JavaScript】内置对象 ③ ( Math 内置对象 | Math 内置对象简介 | Math 内置对象的使用 )

文章目录 一、Math 内置对象1、Math 内置对象简介2、Math 内置对象的使用 二、代码示例1、代码示例 - Math 内置对象的使用2、代码示例 - 封装 Math 内置对象 一、Math 内置对象 1、Math 内置对象简介 JavaScript 中的 Math 内置对象 是一个 全局对象 , 该对象 提供了 常用的 数…

名家采访:国家级中国茶文化首席非遗传承人——罗大友

“崇高的理想是一个人心中的太阳,能照亮生活中的每一步。”罗大友&#xff0c;性别&#xff1a;男&#xff0c;国家级中国茶文化首席非遗传承人•中国茶文化研究院院长、美国巴拿马太平洋万国博览会终身评委兼中国区联合主席&#xff0c;大学文化&#xff0c;高级政工师。 “第…