
C语言基础
C语言入门
枕上
这个作者很懒,什么都没留下…
展开
-
char *p和 char p[]的区别
#include <stdio.h>#include <string.h>void go(char *str,int len){ strcpy(str,"yujinchi");}int main(){ char str[] = "yuJinChi love tangLiNa"; //char p[]是一个数组,已经分配内存,是将"abc123ABC" 复制到该内存里面,这个内存是可读写的 //char *str.转载 2021-08-23 20:09:43 · 2921 阅读 · 0 评论 -
C语言:static关键字
在 C 语言中,static 关键字不仅可以用来修饰变量,还可以用来修饰函数。在使用 static 关键字修饰变量时,我们称此变量为静态变量。静态变量的存储方式与全局变量一样,都是静态存储方式。但这里需要特别说明的是,静态变量属于静态存储方式,属于静态存储方式的变量却不一定就是静态变量。例如,全局变量虽然属于静态存储方式,但并不是静态变量,它必须由 static 加以定义后才能成为静态全局变量。1、隐藏与隔离的作用上面已经阐述过,全局变量虽然属于静态...转载 2021-09-07 12:59:42 · 443 阅读 · 0 评论 -
while循环不断申请一个变量
#include <stdio.h>int main(){ while(1){ int a = 10; printf("a = %d\n",a); sleep(2); } return 0;}没有错误,这个a属于局部变量,每一次循环的过程结束的时候都会先释放他占用的内存,然后再重新申请内存...原创 2021-08-13 15:18:41 · 793 阅读 · 0 评论 -
C语言:段错误产生原因及简单的调试方法
段错误产生原因1.访问不存在的内存地址如下面代码,ptr没有申请空间就直接拷贝数据:#include<stdio.h>#include<string.h>#include<stdlib.h>intmain(intargc,char*argv[]){char*ptr=NULL;//This is the wrong implementation:strncpy(ptr,"abc",3);//ptr没有申...原创 2021-08-05 21:01:01 · 11441 阅读 · 0 评论 -
C程序中的内存分布_2
C语言变量的内存分配及储存位置的探究最近学习C语言,对变量的储存位置很不清楚,后来通过多次查询资料有了自己的见解,特写此博客分享自己对C语言在内存中的储存过程的理解,如有错误望指正。一、虚拟内存首先要知道,我们在应用程序中所使用的地址均是虚拟内存地址,在32位操作系统中,每一个进程所占用的虚拟内存是4G,4G的虚拟内存又分为1G的内核空间和3G的用户空间,内核空间是当前主机中所有进程共有的,用户空间是当前进程私有的,下面讲解的内存区域的划分,指的是用户空间的划分。二、虚拟内存用户空间的区域划分转载 2021-08-02 17:31:09 · 171 阅读 · 0 评论 -
C程序中的内存分布
原博文:https://www.cnblogs.com/miaoxiong/p/11021827.html一个典型的C程序存储分区包含以下几类:Text段 已初始化数据段 未初始化数据段 栈 堆 进程运行时的典型内存布局1. Text段Text段通常也称为代码段,由可执行指令构成,是程序在目标文件或内存中的一部分,Text段通常放在栈或堆的下面,以防止堆栈溢出篡改其数据。通常情况下,Text段是可共享的,对于需要频繁调用的程序,其在内存中只需要一份拷原创 2021-08-02 16:58:33 · 715 阅读 · 0 评论 -
C语言:传值与传指针的区别
原博文:https://www.jb51.net/article/163713.htm前言我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。传值我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15原创 2021-07-31 09:49:33 · 600 阅读 · 0 评论 -
4.联合体(共用体) / union
转载:https://www.linuxidc.com/Linux/2019-01/156153.htm(结构体与联合体的分析比较)共用体(联合体) / union有时,我们需要使几种不同类型的变量存放到同一段内存单元中。例如,可以把一个整型变量(2 个字节)、一个字符型变量(1 个字节)、一个实型变量(4 个字节)放在同一开始地址的内存单元中,如下图所示:以上 3 个变量在内存中占的字节数不同,但都从同一地址开始存放,也就是几个变量相互覆盖。这种使几个不同的变量共占同一段内存的结...原创 2021-04-24 16:28:37 · 783 阅读 · 0 评论 -
C语言:结构体的对齐和计算大小
我们实际生活中,保存的数据一般不会是同一种类型,所以引入了结构体。而结构体的大小也不是成员类型大小的简单相加。需要考虑到系统在存储结构体变量时的地址对齐问题。由于存储变量地址对齐的问题,结构体大小计算必须满足两条原则:一、结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)二、结构体总大小必须是所有成员大小(数组,结构体除外)的整数倍对齐方式很浪费空间,确实。。 可是按照计算机的访问规则,这种对齐方式提升了效率#include <stdio.h>#incl.原创 2021-07-26 16:29:07 · 275 阅读 · 0 评论 -
C语言:冒泡排序和选择排序
冒泡排序:原理:从左到右相邻元素进行比较,每比较一轮找到序列中最大或者最小的一个,这个数会从右边冒出来。第一轮比较:所有数最大的会浮现到最右边第二轮比较,所有数第二大的数会浮现到倒数第二个位置有 n 个数据需要比较(n-1)轮,除第一轮外都不用比较全部int main(){ int i,j,t,len; int a[] = {11,2,6,15,0}; len = sizeof(a)/sizeof(a[0]); for(i=0;i<原创 2021-07-26 13:58:14 · 257 阅读 · 0 评论 -
# 和 ## 的区别
# :1、最常见的是 #不会替换参数,只替换其所对应的字符 2、 把宏参数变成一个字符串;## :把两个宏参数连接到一起(只能两个)#include <stdio.h>#include <stdlib.h>#define ONE 1 //1.最常见的是 #不会替换参数,只替换其所对应的字符; #define toString(str) #str //2.转字符串#define hehe(x,y) x##y //连接int ma...原创 2021-07-25 08:23:40 · 3516 阅读 · 0 评论 -
ifndef 详解
原博文:https://www.cnblogs.com/codingmengmeng/p/7221295.html#ifndef 是"if not defined"的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是: 1、防止头文件的重复包含和编译; 2、便于程序的调试和移植; 下面分别举例描述。一、防止头文件的重复包含和编译下面是错误示范:headfile_1.h#include <iost原创 2021-07-25 07:17:36 · 1440 阅读 · 0 评论 -
fgets( )函数获取有效字段
if((p = strchr(clientHandler->comand,'\n')) != NULL) *p = '\0';原创 2021-07-20 17:41:25 · 262 阅读 · 0 评论 -
多级指针(静动态内存的跨函数访问)
多指针初认识:#include <stdio.h>#include <stdlib.h>int main(){ int i = 100; int *p = &i; int **q = &p; int ***r = &q; //r = &p; //error 因为r是 int*** 类型,r只能存放 int** 类型变量的地址 printf("i = %d\n",***r); .原创 2021-07-15 00:27:17 · 208 阅读 · 0 评论 -
为什么不直接调用函数而要使用函数指针?
作者:庄严链接:https://www.zhihu.com/question/349498301/answer/1492253088来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。函数指针让“函数”可以是一个“变量”。通常我们认为一件事由“动作”和“数据”组成,比如“小明泡妞”中,小明是数据,妞是数据,泡是动作。动作和数据边界清晰,各自含义也直观。把动作数据化,真的是各种编程语言一路下来心心念念的要有各种实现各种改进的念想。就以典型面向过程式的C语言为例:.原创 2021-06-20 06:11:06 · 3072 阅读 · 7 评论 -
C语言:typedef关键字
目录1.typedef关键字干嘛的2.在单片机开发当中,寄存器8位,16位,32位3. 和结构体结合命名: 3.1普通重命名。 3.2重命名的另一种,把结构体本身给的名字Student的去掉。 3.3普通重命名后附带命名一个指针(最常见)。 3.3结构体里的函数指针,不能使用结构体括号外的名字4. typedef关键字和结构体的使用,代码如下:1.typedef关键字干嘛的 typedef为C语言的关键字 ...原创 2021-03-29 04:20:25 · 773 阅读 · 0 评论 -
C语言:结构体指针操作学生成绩(再次了解结构体指针的使用)
1.定义一个数组:数组里面的每一个元素代表一个学生:1.1第一种定义方式:直接声明一个指针指向数组。 struct Student stus[3]; struct Student *p = stus;1.2第二种定义方式:用指针指向malloc开辟一个数组空间,数组的另一种定义方式。 struct Student *p; p = (struct Student *)malloc(3 ...原创 2021-03-28 15:43:33 · 2452 阅读 · 0 评论 -
C语言:结构体指针
使用结构体指针注意点:1.如果用结构体指针,就不能用(点运算符)访问结构体中的变量,要用->比如:stu.score = 50; 变成 stu->score = 50;2.指针要注意是否是野指针或者NULL,非法内存,会段错误,使用前要malloc比如:struct Student *p;(野指针) 或 struct Student *p = NULL; 3.如果结构体指针发生偏移。则是偏移整个结构体的大小。struct Student...原创 2021-03-28 03:24:14 · 13530 阅读 · 5 评论 -
C语言:结构体数组来玩成绩(加深入门结构体理解)
其实 结构体数组 的使用和 普通数组 是一样的,新知识,旧用法。主要注意:野指针的使用需要malloc即可#include <stdio.h>#include <stdlib.h>struct student{ int score; char *name;};int main(){ struct student stus[3]; struct student maxStu; struct student minStu; .原创 2021-03-28 02:38:54 · 138 阅读 · 0 评论 -
C语言:结构体的定义,使用和访问
#include <stdio.h>#include <stdlib.h>struct students{ int score; char name[128];};int main(){ struct students stu = {98,"娜娜"}; printf("结构体stu中的学生分数是:%d\n",stu.score); printf("结构体stu中的学生名字是:%s\n",stu.name); s.原创 2021-03-27 02:32:43 · 460 阅读 · 4 评论 -
C语言:自己实现字符串API(利用字符串的特点,结尾是‘\0‘)
自己实现部分字符串API:重点:(就是利用字符串的特点,结尾是’\0’)puts( )gets( )memset( )1.自己实现puts( )#include <stdio.h>#include <stdlib.h>void myPuts(char *p){ while(*p != '\0'){ putchar(*p++); *p++ :从左往右,先取p的内容,再++ //printf("%c",*p++); } putcha原创 2021-03-26 21:12:00 · 135 阅读 · 0 评论 -
C语言:API__字符串的分割:strtok()
原型: char *strtok(char *str,const char *delim) 第一个参数:要分割的字符串 第二个参数:要以哪个字符类型来分割 返回值: 该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。当strtok()在参数str的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,str指向要分解的字符串,往后的调用则将参数str设置成NULL。每次调用成功则返回指向被分割出片段的指针,如果没有可检索原创 2021-03-26 18:01:38 · 332 阅读 · 0 评论 -
C语言:字符串API__找子字符:strchr(),找子串:strstr(),转为大小写
1.查找子字符:strchr()函数原型char *strchr(const char *str, char c)参数str 要被检索的 C 字符串。c 在 str 中要搜索的字符。功能在参数str所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。返回值返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。头文件#include <string.h> char *str = "yujinchi"; ch原创 2021-03-26 10:50:34 · 305 阅读 · 0 评论 -
C语言:字符串API_拼接strcat(),比较strcmp()
1.字符串的拼接:strcat()原型:char *strcat(char *dest, const char *src) char *strSrc = "初入门"; char test[128] = "学习C语言之路----"; strcat(test,strSrc); puts(test); 2.字符串的比较:strcmp()原型:int strcmp(const char *s1,const char *s2)strcmp函数是string com原创 2021-03-25 20:43:00 · 476 阅读 · 0 评论 -
C语言:什么是内存泄漏,如何避免
1.内存泄露的现象程序刚跑起来的时候很好,跑一段时间之后,或者几天,或者几周之后,程序崩溃。2.malloc申请的空间,程序不会主动释放。linux种的话,程序结束后,系统会回收这个空间。while(1){ sleep(1); int *p = (int *)malloc(1024);}代码的意思是:一个while循环,每隔一秒开辟一个1兆的空间,不断开辟,程序不结束,系统不回收,导致内存泄漏。3.如何避免内存泄漏:(1)注意,循环中有没有一直申请空间(2)及时合理的释放,使用fre原创 2021-03-22 12:21:04 · 1297 阅读 · 0 评论 -
C语言:无类型指针_malloc(第四种定义数组的方式)
C语言中的内存分配函数:void* malloc(size_t size);malloc向系统申请分配制定size个字节的内存空间。返回类型是void类型。在C语言中,void类型可以强制转换为任何其他类型的指针。.1.单一整型数空间开辟int *a = (int*)malloc(sizeof(int)).2.多个整数空间的开辟,此时也是一个_(数组)。int *parray = (int *)malloc(n * sizeof(int));n 表示个数,意思是开辟了n个int整型数空原创 2021-03-22 11:56:39 · 772 阅读 · 0 评论 -
C语言:数组指针(一个指针)
1.数组指针的定义及赋值:int a[3] = {1,2,3};int (*p)[3]; 定义p = a; 或 p = &a[0] 赋值2.与普通指针指向数组命名的区别int a[3] = {1,2,3};1.普通指针指向数组int *p;p = a; 2.数组指针指向数组int (*p2)[3];p2 = a;.3.数组指针与普通指针指向数组的根本区别(1)共同点:都是指向了相同的地址位置(2)不同点:偏移值不同。普通指针指向数组偏移的时候原创 2021-03-21 14:25:26 · 448 阅读 · 0 评论 -
C语言:函数指针
一:函数指针关键点:例子:int(*p)( int a ,int b);1.如何表示指针: *2.如何知道是函数:()3.函数指针是专用的,格式要求很强(参数类型,个数,返回值),就像数组指针一样.二:如何定义函数指针并且赋值如果被调用的函数是:int dis(int a,intb){ return a+b;}则定义函数指针的时候,将上面的函数int dis(int a ,int b)拷贝到main函数中,并将dis换成新的名字如(*p),这样做的好处是不容易出错。int (*p原创 2021-03-21 13:09:29 · 130 阅读 · 0 评论 -
C语言:指针数组(多个指针)
一:指针数组 ,在数组中的每一项元素都是一个指针变量(也就是一个地址)1.定义一个指针数组:int *parray[ ] ; … //多个指针就做指针数组…2.定义后的初始化及遍历,具体代码如下:#include <stdio.h>#include <stdlib.h>int main(){ int a = 2; int b = 3; int c = 4; int *p[3]; p[0] = &a;原创 2021-03-21 10:39:22 · 1040 阅读 · 0 评论 -
C语言:指针的偏移
指针的偏移值是多少取决于指针的类型:int a = 10;char c = ‘A’;int *p;char *p2;p = &a;p2 = &c; //p++ (自身运算)之后再加1 printf("a的地址的打印:%p\n",p); //++p (自身加1运算)之后再下一步printf("a的地址++打印:%p\n",++p); //int型 偏移了4个字节printf("c的地址的打印:%p\n",p2);print原创 2021-03-20 16:35:52 · 1094 阅读 · 0 评论 -
C语言:指针遍历访问数组中的值【scanf取地址问题】,此时的parray[i] 等于 array[i]
/.指针变量访问数组的值:/ int array[3] = {1,2,3}; int *parray; parray = array; //或者parray = &array[0]; .对于 :parray = array; //或者parray = &array[0];(数组,关心的是数组的首地址 ,两种方式表示:1.数组名 = 地址 2.第一个元素的地址)).//1.普通的访问: printf(“第一个元素的地址:%p\n”,pa原创 2021-03-20 16:45:15 · 516 阅读 · 0 评论 -
C语言:字符串API拷贝_strcpy(),strncpy,给(数组名)赋值字符串要用strcpy
1.字符串的拷贝API:strcpy() 原型:char *strcpy(char* dest,const char *src) - 第一个参数dest:目标函数 - 第二个参数src:原函数 char strDest[128] = {'\0'}; 第一种定义初始化数组 char *strSrc = "hello world"; strcpy(strDest,strSrc); printf("复制字符串完毕:%s\n",strDest);=======原创 2021-03-25 12:05:22 · 1577 阅读 · 0 评论 -
C语言:字符串API_gets()及指针的另一种初始化用memset()函数
1.先尝代码: char *p; 野指针 造成非法内存访问 ,会出现段错误,cmd窗口闪退 p = (char *)malloc(128); 申请空间malloc if(p == NULL){ 一旦用了malloc,一定要注意内存泄漏的问题。malloc可能会失败,要对返回值做判断 printf("申请内存失败\n"); exit(-1); -1代表是程序是非正常退出 } memset(p,'\0',128);原创 2021-03-25 03:43:13 · 240 阅读 · 0 评论 -
C语言:字符串在内存中的储存方式和计算字符串的大小
1.字符串的存储方式 :字符串在内存中,除了有效字符以外的,还会自动在后面补一个’\0’,作为字符串的结束标识。2.真正计算有效字符的长度 用 strlena4[ ] 中的 [ ] 不写大小,数组的大小是会根据初始化的时候元素个数来确定 char a4[] = "abc"; 连续的空间,整个数组的大小是 元素个数乘以元素类型的大小 printf("a数组的大小是:%d\n",sizeof(a4)); 结果是4! printf("a数组的大小是:%d\n",str原创 2021-03-23 17:02:05 · 6260 阅读 · 2 评论 -
C语言:字符串的定义(也叫字符数组)
一:定义字符串的方法有四种:.1.最常用的:数组名就是地址(大多数情况下),指针也是地址 char *str4 = "abcdefghij"; 指针方式,如果操作不当,内存非法,易造成段错误 sigment error printf("%s\n",str4); 字符出啊用格式占位符&s表示,不需要用i的下标来遍历2.较差的和整数数组类似数组元素个数不写,会根据真实的大小来默认分配 int i; char str3[ ] = "abcde"; 数组元原创 2021-03-23 16:19:14 · 18274 阅读 · 0 评论 -
C语言:函数中实参与形参的关系
函数中:传参的过程,实际上就是一个赋值的过程,是将实参中的值赋值给形参(也可以说是形参拷贝了一份实参的值)…1.形参只有函数被调用的时候才存在2.形参的值在没有传实参的值的地址的时候,形参中的值的更改不影响实参中的值#include <stdio.h>#include <stdlib.h>void jiaA(int a){ a = a + 1; printf("jiaA函数中a = %d\n",a); }void jiaB(int *a){ *.原创 2021-03-20 18:37:01 · 1584 阅读 · 0 评论 -
C语言:数组和函数(算数组大小,数组传参,数组形参)
一.数组的大小计算: int a[3]; //一个整型数占用空间4个字节,3个占用空间12个字节char b[3]; //一个char型占用空间1个字节,三个占用空间3个字节 printf("a数组的大小是:%d\n",sizeof(a)); printf("b数组的大小是:%d\n",sizeof(b)); printf("一个整数的空间是:%d\n",sizeof(a[0])); printf("一个字符型数的空间是:%d\n",sizeof(char));//两个数组有原创 2021-03-13 14:27:17 · 3101 阅读 · 1 评论 -
C语言:数组的定义
一:数组的特征1、数组是数据的集合 比如1到1002、数组的数据是同类型的 1–100都是整数,. …不能 1 1.2 2 2.43、数组地址是连续的二:定义数组的三种方式***//// 注意:数组中括号[ ] 只有在定义一个数组的时候,才表示数组大小,其余任何情况,都表示用下标来访问数组***1、没有初始化的数组,仅仅申请了100个整数型的内存空间, 最好要初始化:int array[100] = (0); 每一个都赋值为0 int array[1原创 2021-03-19 06:21:16 · 21917 阅读 · 2 评论 -
C语言:指针的定义和赋值及访问变量,* 号在不同情况下的意思
指针也是一种变量:指针存放的是地址不同于整形变量int型存放的是整数,或者字符变量char型存放的是字符等变量,指针变量存放的是"地址"。int a = 10;第 1 种写法:int* p ; //定义一个指针变量 p = &a; //给指针变量赋值或第 2 种写法:int *p = &a; //定义并初始化一个指针变量****但是不能:*p = &a; //这是典型的错误的写法为什么不能这么写:因为 * 只有在定义一个指针变量的原创 2021-03-20 14:54:45 · 1151 阅读 · 0 评论 -
c语言中:=和==的区别是什么?
= 是赋值操作==是比较是否相等操作if(a=2)是永远成立的,意思是:把2的值赋值给变量a。if(a2)只有当i值是2才成立,这是看“a”和“2”是否相等,如果相等的话这句话返回“true”(可以理解为“a2”这句话就等于“true”),如果不相等返回“false”。...原创 2021-03-19 05:41:04 · 6453 阅读 · 0 评论