C语言的学习
文章平均质量分 70
C语言的语法和题目
林林林ZEYU
坚持
展开
-
921-实现一个memcpy
实现一个memcpy#include <iostream>using namespace std;void* Memcpy(void* dst, const void* src, size_t size){ char* pdst = (char*)dst; char* psrc = (char*)src; if (dst == NULL || src == NULL) return NULL; //如果src和dst有重叠,则从后往前进行原创 2021-12-26 01:12:57 · 419 阅读 · 0 评论 -
805-解决汉诺塔问题
汉诺塔问题汉诺塔问题源自印度一个古老的传说,印度教的“创造之神”梵天创造世界时做了 3 根金刚石柱,其中的一根柱子上按照从小到大的顺序摞着 64 个黄金圆盘。梵天命令一个叫婆罗门的门徒将所有的圆盘移动到另一个柱子上,移动过程中必须遵守以下规则:每次只能移动柱子最顶端的一个圆盘;每个柱子上,小圆盘永远要位于大圆盘之上;图 1 展示了包含 3 个圆盘的汉诺塔问题:一根柱子上摞着 3 个不同大小的圆盘,那么在不违反规则的前提下,如何将它们移动到另一个柱子上呢?图 2 给大家提供了一种实现方案:原创 2021-11-13 22:32:47 · 2230 阅读 · 0 评论 -
796-void与void* 详解
void关键字的使用规则1、如果函数没有返回值,那么应声明为void类型;2、如果函数无参数,那么应声明其参数为void;3、如果函数的参数可以是任意类型指针,那么应声明其参数为void * ;4、 void不能代表一个真实的变量;void体现了一种抽象,这个世界上的变量都是“有类型”的void的含义void的字面意思是“无类型”,void * 则为“无类型指针”,void *可以指向任何类型的数据。void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来原创 2021-11-11 19:07:09 · 308 阅读 · 0 评论 -
795-C语言指针和数组的区别
仔细查看以下代码,print_arr_addr和print_g_arr_addr的打印输出地址相同么?为什么?数组与指针的区别数组和指针是如何访问的?数组和指针的定义和声明定义: 只能出现在一个地方,它会为对象分配内存声明: 可以出现在多个地方,描述对象的类型,用于指代其他地方定义的对象//x是一个指向int型的指针的声明extern int *x;//y是一个int型数组的声明extern int y[];//定义指针xint *x;//定义数组yint y[10];数组下原创 2021-11-11 14:18:21 · 179 阅读 · 0 评论 -
793-C语言字符数组和字符串详解
C语言字符数组和字符串详解用来存放字符的数组称为字符数组,例如:char a[10];//一维字符数组char b[5][10];//二维字符数组char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'};//给部分数组元素赋值char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' };//对全体元素赋值时可以省去长度字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语原创 2021-11-10 18:27:38 · 1105 阅读 · 0 评论 -
792-C语言二维数组的定义和使用
二维数组的定义二维数组定义的一般形式是:dataType arrayName[length1][length2];其中,dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。我们可以将二维数组看做一个 Excel 表格,有行有列,length1 表示行数,length2 表示列数,要在二维数组中定位某个元素,必须同时指明行和列。例如:int a[3][4];定义了一个 3 行 4 列的二维数组,共有 3×4=12原创 2021-11-10 14:17:44 · 2833 阅读 · 0 评论 -
791-C语言数组的概念和使用
C语言数组的概念和使用我们看下面代码:#include <stdio.h>#include <stdlib.h>int main(){ int a1=20, a2=345, a3=700, a4=22; int b1=56720, b2=9999, b3=20098, b4=2; int c1=233, c2=205, c3=1, c4=6666; int d1=34, d2=0, d3=23, d4=23006783; printf原创 2021-11-09 22:41:29 · 859 阅读 · 0 评论 -
790-C语言的数组元素下标为何从0开始?
C语言的数组元素下标为何从0开始?我们在学习数组时会有这个疑问,数组元素的下标为什么不从1开始呢?从1开始不是更符合大家的日常习惯吗?生活中我们通常说第1个,而不是第0个。的确,有些计算机语言如早期的Pascal语言,数组元素的下标是从1开始的。难道是C语言故意要与众不同?要弄清楚这个问题,得先看一下计算机底层是怎样处理数组元素的。我们先编写了一个小程序,然后在VS编译器中对其进行了反汇编。源代码和反汇编后的部分代码如下:int arr[5];//一个全局数组int main(){ in原创 2021-11-09 20:45:39 · 2251 阅读 · 0 评论 -
789-C语言函数指针(指向函数的指针)
C语言函数指针(指向函数的指针)一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个**首地址(或称入口地址)**赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是函数指针。函数指针的定义形式为:returnType (*pointerName)(param list);returnType 为函数返回值类型,pointerName 为指针名称,param li原创 2021-11-09 19:06:10 · 375 阅读 · 0 评论 -
786-C语言位域(位段)详解
C语言位域(位段)详解有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。请看下面的例子:struct bs{ unsigned m; unsigned n: 4; unsigned char ch: 6;};:后面的数字用来限定成原创 2021-11-09 00:03:11 · 251 阅读 · 0 评论 -
785-C语言位运算(按位与运算、或运算、异或运算、左移运算、右移运算)
C语言位运算所谓位运算,就是对一个比特(Bit)位进行操作。比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了。C语言提供了六种位运算符:按位与运算(&)一个比特(Bit)位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。例如1&1为 1,0&0为 0,1&0也为 0,这和逻辑运算符&&非常类似。C语言中不能直接使用二进制,&两边的操作数可以是十原创 2021-11-08 23:24:03 · 799 阅读 · 0 评论 -
784-C语言rand和srand用法详解
C语言rand和srand用法详解在实际编程中,我们经常需要生成随机数,例如,贪吃蛇游戏中在随机的位置出现食物,扑克牌游戏中随机发牌。在C语言中,我们一般使用 <stdlib.h> 头文件中的 rand() 函数来生成随机数,它的用法为:int rand (void);void 表示不需要传递参数。C语言中还有一个 random() 函数可以获取随机数,但是 random() 不是标准函数,不能在 VC/VS 等编译器通过,所以比较少用。rand() 会随机生成一个位于 0 ~ R原创 2021-11-08 21:31:00 · 407 阅读 · 0 评论 -
779-如何防止C语言头文件被重复包含
如何防止C语言头文件被重复包含?一般情况下,我们都是把函数声明、类定义、模板定义等写到一个头文件里,需要时将相应的头文件用#include包含到源文件(*.c文件)里来。但头文件中又允许包含其它的头文件,这样就难免发生某个头文件被重复地包含。我们可以使用编译预处理命令避免这种情况的发生。方法1:使用#ifndef例如,你想确保头文件max.h不会被重复包含,则你可以采取如下的形式:第一条预处理命令的意思:如果MAXMIN_H不为真,说明此文件没被包含过,此命令后面的源代码有效(相当于:‘如果大门原创 2021-11-08 14:21:49 · 4762 阅读 · 1 评论 -
770-C语言return的用法详解,C语言函数返回值详解
C语言return的用法详解函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这个结果通过 return 语句返回。return 语句的一般形式为:return 表达式;或者:return (表达式);有没有( )都是正确的,为了简明,一般也不写( )。例如:return max;return a+b;return (100+200);对C语言返回值的说明1、没有返回值的函数为空类型,用void表示。例如:void func(){ printf("http原创 2021-11-07 13:31:33 · 1784 阅读 · 0 评论 -
766-C语言内存操作函数的实现
C语言内存操作函数的实现memcpy内存拷贝函数void* memcpy(void* destination, const void* source, size_t num);memcpy函数从source的位置开始向后拷贝num个字节的数据到destination的内存位置这个函数在遇到\0的时候并不会停下来如果source和destination有任何的重叠,复制的结果都是未定义的使用方法:#include <stdio.h>#include <string.h>原创 2021-11-05 21:46:00 · 264 阅读 · 0 评论 -
756-如何判断合法的IP地址,尽可能考虑各种情况
如何判断合法的IP地址,尽可能考虑各种情况判断IPV4的地址是否合法的程序只对IP地址如下规则做了判断:IP地址的规则是: (1 ~ 255).(0 ~ 255).(0 ~ 255).(0 ~ 255)。例如192.168.2.1#include<stdio.h>#include<ctype.h>static int CountPoint(const char* str)//计算字符串的.的个数{ int count = 0; while (*str原创 2021-11-04 14:03:05 · 1398 阅读 · 0 评论 -
755-C语言的断言assert
大多数编程语言也都有断言这一特性。简单地讲,断言就是对某种假设条件进行检查。即如果此宏的函数形式的参数表达式比较为零(即表达式为false),则向标准错误设备写入一条消息并调用abort,终止程序的执行。可以简单理解为下面的代码段:if(假设成立){ 程序正常运行;}else{ 报错&&终止程序!(避免由程序运行引起更大的错误) }但是多数情况下,我们要进行验证的假设,只是属于偶然性事件,又或者我们仅仅想测试一下,一些最坏情况是否发生,所以这里有了原创 2021-11-04 00:00:58 · 391 阅读 · 0 评论 -
754-C语言字符串操作函数的代码实现
C语言字符串操作函数的代码实现在编写程序的过程中,我们经常使用到一些字符串函数,例如求字符串长度,拷贝字符串,拼接字符串,比较字符串大小等等,这些函数都在C标准库中存在,我们可以直接使用。但我们还需要掌握这些函数的实现方法,今天来看看一些常用的字符串操作函数的实现方法。strlenstrlen是用来求字符串长度的函数,字符串长度就是它所包含的字符个数(求的是\0前的字符的个数)。3种实现strlen函数的方法:1、定义一个计数器countsize_t my_strlen(const char*原创 2021-11-03 22:14:42 · 236 阅读 · 0 评论 -
733-实现一个宏,计算结构体成员的相对偏移量
获取一个结构体成员相对于该结构首地址的偏移量#include <stdio.h>#define GET_OFFSET(data,member) (size_t)(&(((typeof(data)*)0)->member))typedef struct student { int a; char ch[2]; double d;}student_t;int main(int argc, char const* argv[]){原创 2021-10-29 20:46:48 · 203 阅读 · 0 评论 -
731-用一维数组打印杨辉三角(面试题)
用一维数组打印杨辉三角(面试题)我们定义n,表示打印的层数。我们定义l,表示当前位置的上一层的左边位置。我们定义r,表示当前位置的上一层的位置。从第一层开始,最外层的循环次数是层数。内层的循环次数是当前层的元素个数。把数组arr初始化为arr[]={0,1,0,0,0…};从第一层开始打印下去。int main(){ int arr[100] = { 0,1 };//初始化数组 int n, i, j; int l, r;//存放上一层左边的数和上一层的数 n = 10;//层数原创 2021-10-29 20:08:00 · 178 阅读 · 0 评论 -
729-汇编push和pop指令
汇编push和pop指令push和pop是用来操作栈的2个指令。push 寄存器:将一个寄存器中的数据入栈。pop 寄存器:出栈用一个寄存器接收数据。assume cs:codesg ;cs寄存器指向该程序的首地址codesg segment mov ax,1000H ;将1000H送入寄存器ax,相当于ax=1000H mov ss,ax mov sp,0010H mov ax,001AH ;将ax,bx赋值 mov bx,0原创 2021-10-29 10:39:00 · 13752 阅读 · 0 评论 -
721-统计英文文档中重复次数最多的前1000个单词
统计英文文档中重复次数最多的前1000个单词,按重复次数从大到小输出,并保存到文件#include <stdio.h>#include <assert.h>#include <ctype.h>#include <stdlib.h>#include <string.h>/*项目一:统计英文文档中重复次数最多的前1000个单词,按重复次数从大到小输出,并保存到文件 sprintf();*/#define WORD_LEN 100原创 2021-10-26 18:36:10 · 266 阅读 · 0 评论 -
720-C语言实现2048游戏
C语言实现2048游戏#include <stdio.h>#include <stdlib.h>#include <time.h>#include <conio.h>#include <windows.h>#define ROW 4#define COL ROW#define KEY1 224#define KEY_LEFT 75#define KEY_UP 72#define KEY原创 2021-10-26 18:24:28 · 2210 阅读 · 0 评论 -
705-C语言的typedef关键字
C语言的typedef关键字我们看看个关键字的名字:type是类型,def是定义。所以typedef:类型定义我们先看看下面例子:我们得明白:在C语言中,main函数中的struct关键字是不能省略的,在C++中是可以省略的。在C语言中,怎么样才可以省去main函数中struct的书写?typedef的应用场景类型定义,1、给类型起个简短的别名2、根据数据特征,起别名比如说size_tsize_t用在数据领域上。并不是新的数据类型,只是把已有的数据类型包装了。我们再来看看:原创 2021-10-18 10:04:27 · 721 阅读 · 0 评论 -
704-什么是位段?
什么是位段(位域)?位段的来历:很久以前,内存特别小,有时候我们定义一个整型变量(32位),实际上我们只使用6位,或者7位,然后我们却使用的是32位的整型变量,这样就浪费了。所以,我们就用位段来表示:int a:8就是把4个字节拆开用,你8位,我20位,他4位。从1到32位,可以任意的拆分来使用位段是历史遗留问题,现在不再使用:因为:假如说,现在有一个32位的内存:可以是a占前面的8位,b占中间的20位,c占后面的4位但是,它也可以这样:a占前面的4位,b占中间的20位,c占后面的8位原创 2021-10-18 09:03:09 · 147 阅读 · 0 评论 -
703-轻松理解C语言的共用体
C语言的共用体共用体:也称为联合体,所有的成员共用内存,也就是意味着所有成员都是从相同的低地址开始。我们先来看看结构体的内存布局:我们现在来看看共用体的内存布局:成员是共用低地址开始的内存。因为成员的大小有可能是不一样的,如果b是char类型的,那么b只占从低地址开始的1个字节大小的内存。但是b还是和a共用低地址开始的内存。对于所有的成员来说,内存都是相同的,从低地址开始。在宿舍,每个成员都有自己的床位,类似于结构体,每个人都有自己独立的内存空间。但是,餐厅是每个成员共用的,就餐座位原创 2021-10-18 08:50:54 · 565 阅读 · 0 评论 -
702-C语言的枚举常量
如果我们要定义一个量来表示星期一到星期日,如果我们定义的是普通的整型变量,那么我们就没有办法控制它的范围。C语言的枚举常量我们把枚举体里的成员称为枚举元素。wx叫做枚举变量枚举变量所取的值必须是枚举体里面的值枚举体里面的这些枚举值,我们称为枚举常量。枚举变量取的值必然是枚举的范围,只能取我们给的星期一到星期日枚举常量的特点我们只能给整型。不能给浮点数等其他任何类型。必须是整型,可以是正数,也可以是负数如果我们不给枚举常量赋值,可不可以呢?可以,如果我们不赋值,枚举值的算法是原创 2021-10-18 00:02:28 · 567 阅读 · 0 评论 -
701-简单易懂的进制转换方法
生活中的进制时间转换:古代的二进制二进制,八进制,十六进制转为十进制10进制,8进制,16进制的取数范围如下:进制转换方法10进制如何转成8进制或者16进制???首先把10进制转成2进制,由2进制转8进制(每3位2进制代表1位8进制)或者16进制(每4位2进制代表1位16进制)10进制转2进制首先,我们把10进制转成2进制,我们可以通过除2取余法,我们也可以通过下面贪心算法这种方法:103不大于128,我们在128的位置填上0103大于64,我们在64的位置填上1然后我们原创 2021-10-18 00:02:21 · 987 阅读 · 0 评论 -
678-C语言中结构体和共用体的区别
结构体和共用体的区别两者最大的区别在于内存的分配结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。一、结构体struct各成员各自拥有自己的内存,各自使用互不干涉,同时存在的,遵循内存对齐原创 2021-10-14 12:35:55 · 2923 阅读 · 0 评论 -
676-为什么要进行结构体内存对齐
为什么要进行结构体内存对齐?1、平台移植型好不是所有的硬件平台都能访问任意地址上的数据;某些硬件平台只能只在某些地址访问某些特定类型的数据,否则抛出硬件异常,及遇到未对齐的边界直接就不进行读取数据了。2、cpu处理效率高从上图可以看出,对应两种存储方式,若CPU的读取粒度为4字节,那么对于一个int 类型,若是按照内存对齐来存储,处理器只需要访存一次就可以读取完4个字节,若没有按照内存对其来读取,如上图所示,就需要访问内存两次才能读取出一个完整的int 类型变量具体过程为,第一次拿出 4个原创 2021-10-13 21:33:29 · 143 阅读 · 0 评论 -
673-C语言笔试题
C语言选择题1、int fun(int m) { static int temp=0; temp+=m; return temp; } void main() { int i=0; int ret=0; for(i=0; i<3; i++) { ret=fun(i); } printf(“%d \n”, ret); } 请选择正确的输出结果: CA.1 B.2 C.3 D.4 2、int x=5; void main() { int s=10;原创 2021-10-10 22:15:51 · 435 阅读 · 0 评论 -
656-C语言的循环结构(2)
do while的典型用法我们看出:while循环是:一上来,先去做while括号里的表达式的条件判断,如果表达式为true ,就进入循环体执行,执行完循环体,又返回到while括号里的条件,进行判断,如果为true,就又进入循环体,如果为false,就跳出整个while循环。do while循环是:一上来先执行do里面的代码(循环体),循环体一次执行完了之后,再去判断while括号里的表达式,如果结果为true,就继续执行一次循环体,然后再判断这个while括号里的表达式,是true还是false。原创 2021-09-27 21:39:22 · 235 阅读 · 0 评论 -
655-C语言的循环结构(1)
串行:从上到下一步一步来。串行的结构是给人看的循环的结构是给计算机看的递归的结构是给神看的循环结构原创 2021-09-27 19:41:55 · 234 阅读 · 0 评论 -
654-C语言的选择结构语句
顺序结构:一行一行往下写选择结构(if else)第一种写法:expr为true的话,进入if语句第二种写法:expr为true的话,进入if语句中执行,如果expr为false的话,进入else语句中执行要么进入if语句,要么进入else语句,是不可能同时进去的。第三种写法:expr1为true的话,进入if语句中执行expr2为true的话,进入else if语句中执行如果前两个都是false的话,进入else语句中执行从上到下依次判断,哪个表达式为true就进入哪个如果ex原创 2021-09-27 14:22:48 · 384 阅读 · 0 评论 -
653-C语言的运算符和表达式(4)
其它运算符梳理下面这2个的结果是一样的:下面这4个的结果是一样的:我们继续看:下面这2种写法是等价的:位运算符内存的最小单位是字节,一个字节是8个位,每个位的取值是0或者1位运算都是针对0或者1运算的。默认的数字被编译器默认为int类型整数浮点数被编译器默认为double为了简单,我们写成1个字节的:按位与&按位与&,都为1才为1,其他情况都是0按位或|只要有1个是1,就为1,按位异或^不一样的才为1按位取反~取反后的值是.原创 2021-09-27 12:37:57 · 164 阅读 · 0 评论 -
652-C语言的运算符和表达式(3)
关系运算符梳理关系运算符也是二目运算符。a>b的本身的结果就是逻辑值/布尔值a是可以加false或者true的,因为true或者false也是一个整数,false对应的是0,在C语言编译器下,true是1算术运算符的优先级是大于关系运算符的:默认执行a+b,然后结果和10比较。现在这种写法是错误的:所以,在C/C++中,判断某一个值在某一个数据的区间之内,我们不能写出成上面这种方式,它和数学上的表示是不一样的。我们之前说过,>=是二目运算符,也就是说它需要2个参原创 2021-09-27 10:48:01 · 456 阅读 · 0 评论 -
651-C语言的运算符和表达式(2)
前置后置+±-运算符是单目运算符,只需要1个参数参与运算我们转到反汇编看看如果把前置++和后置++单独写出来,在汇编指令上是一模一样的。x86的指令,从右往左看,从a这个内存取出4字节,也就是取出a的值10,放在寄存器eax里面,然后add,让eax的值加个1,eax原来的值是a的值10,现在+1,变成11,然后move,把寄存器eax的11放回a的内存里面,就是把a改为11了。现在我们依然看不出来前置++和后置++的区别。如果把前置++和后置++单独写在一行,独立的表达式,是看不出来原创 2021-09-27 09:40:33 · 2002 阅读 · 0 评论 -
650-C语言的运算符和表达式(1)
运算符梳理算术运算符的梳理双目运算符有:做完a+b的值,50000已经超出了short的范围了所以,我们要考虑全面,定义一个合适的类型的变量去接收a+b的值。减法除法也是同理。我们看看除法:没有办法整除的,除法取的是商数,不会进行四舍五入的。我们这样做:如果我们要让除法的结果是正确的并且带有小数:所以我们不能是整数除以整数因为我们直接写一个整数,编译器默认是int,我们直接写一个浮点数,编译器默认是double7.5f让编译器默认是float类型。我们原创 2021-09-26 23:11:52 · 556 阅读 · 0 评论 -
649-C语言的标准输入输出IO函数
标准输入输出IO函数printf和scanf函数printf输出的内容都跑到控制台来了,就是输出到屏幕上。scanf就是从键盘来接收数据。scanf的第一个参数是格式化字符串,我们记得要在第二个参数给变量加上&,给的是变量的地址如果我们万一忘了给变量加上取地址符号&,如下所示:它也没有问题,编译链接是不会给你报错的,你给input的初始化是0,它就给这个scanf的第二个参数替换为0,把0当做是内存地址。也就是,如果你输入了100,它就把100写到0x00000地址里面原创 2021-09-26 22:17:19 · 461 阅读 · 0 评论 -
648-C语言的格式化字符的应用实践
C语言的标准IO即标准的输入输出标准的输入:键盘标准的输出:屏幕(控制台)scanf和printf是格式化的输入和输出格式化:根据用户指定的格式化字符进行输入输出格式化字符的应用实践printf是可变参,参数个数是可以变的。printf的第一个参数永远是是字符串,这个字符串包含自己写的描述内容,和格式化字符。第一个参数:格式化字符串里包含了多少个格式化字符,后面就添加多少个参数。%d是有符号的整数的输出%u是无符号的整数的输出尽量是根据变量的类型,使用对应的输出格式化字符所以原创 2021-09-26 20:55:11 · 249 阅读 · 0 评论