国嵌C语言(6-10)

article/2025/11/6 0:21:10

国嵌六:

空结构体的内存:

struct D
{};
int main(void)
{struct D d1;struct D d2;printf("%d\n",sizeof(struct D));printf("%d,%0x\n",sizeof(d1),&d1);printf("%d,%0x\n",sizeof(d2),&d2);
}

0

0,28ff20

0,28ff20

空结构体占据多大内存不同的编译器结果不同,最合理的是一个字节;codeblocks为1个字节。

由结构体产生柔性数组:

  • 柔性数组即数组大小待定的数组;例子中的array[]。
  • C语言中的结构体的最后一个元素可以是大小未知的数组。
  • c语言中可以有结构体产生柔性数组。

#include <stdio.h>
typedef struct _soft_array
{int len;int array[];                                //不知道大小的情况下默认为0
}SoftArray;
int main()
{int i = 0;//printf("%d\n",sizeof(SoftArray));//所以打印出的结果是4SoftArray* sa=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*10);sa->len = 10; //指定len后面数组的长度为10for(i=0; ilen; i++){sa->array[i] = i + 1;}for(i=0; ilen; i++){printf("%d\n", sa->array[i]);}free(sa);return 0;
}

1,2,3,4,5,6,7,8,9,10

斐波拉茨序列(杨辉三角):

  • 创建柔性数组的结构: typedef struct
  • 创建柔性数组: create_soft_array
  • 生成斐波拉茨序列: fac
  • 释放柔性数组; delete_soft_array
#include <stdio.h>
typedef struct _soft_array
{int len;int array[];
}SoftArray;
SoftArray* creat_soft_array(int size)
{SoftArray* ret=NULL;if(size>0){ret=(SoftArray*)malloc(sizeof(*ret)+sizeof(*(ret->array))*size);ret->len=size;}return ret;
}
void fac(SoftArray* sa)
{int i=0;if(NULL!=sa){if(1==sa->len){sa->array[0]=1;}else {for(i=2;i<sa->len;i++){sa->array[i]=sa->array[i-1]+sa->array[i-2];}}}
}
void delete_soft_array(SoftArray* sa)
{free(sa);
}
int main()
{int i=0;SoftArray* sa=creat_soft_array(10);fac(sa);for(i=0;i<sa->len;i++){printf("%d\n",sa->array[i]);}delete_soft_array(sa);return 0;
}

1,1,2,3,5,8,13,21,34,55

union与struct的区别:

  • struct中的每个域在内存中都是独立分配空间;
  • union只分配最大域的空间,所有的域共享这个空间;
struct A
{int a;int b;int c;
};
union B
{int a;int b;int c;
};
int main(void)
{printf("%d\n",sizeof(struct A));printf("%d\n",sizeof(union B));
}

12,4

nuion的使用受系统大小端的影响:

 大端模式:在高地址的地方放低位的值

小端模式:在低地址的地方放低位的值

union C                    //占用四个字节
{int i;char c;
};
int main()
{union C c;c.i=1;printf("%d\n",c.c);
}

大端模式应该是0;小端模式应该是1;

国嵌七:

枚举类型的使用方法:

  • enum(枚举类型)是一种自定义的类型;
  • enum默认常量在前一个值得基础上依次加1,
  • enum类型的变量只能取定义时的离散值。
#include <stdio.h>
#include <malloc.h>
enum Color
{GREEN, //注意标点符号,第一个不给初始值,默认为0RED=2,BLUE
};
int main(void)
{enum Color c=GREEN;enum Color b=BLUE;printf("%d\n",c);printf("%d\n",b);
}

0,3

枚举类型与#define的区别:

  • #define宏常量只是简单的进行值替换,枚举常量是真正意义上的常量。
  • #define宏常量无法被调用,枚举常量可以。
  • #define宏常量无类型信息,枚举常量是一种特定类型的常量。

typedef的意义:

  • typedef用于给一个已经存在的数据类型重命名;
  • typedef并没有产生新的类型;
  • typedef重定义的类型不能进行unsigned和signed扩展。

 typedef与#define的区别:

(1)原理不同

  •  #define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。
  •  typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域内给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。

(2)功能不同

  • typedef用来定义类型的别名,起到类型易于记忆的功能。另一个功能是定义机器无关的类型。如定义一个REAL的浮点类型,在目标机器上它可以获得最高的精度:typedef long double REAL, 在不支持long double的机器上,看起来是这样的,typedef double REAL,在不支持double的机器上,是这样的,typedef float REAL
  • #define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

(3)作用域不同

  • #define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,
  • typedef有自己的作用域。

(4)对指针的操作不同 

#define INTPTR1 int*
typedef int* INTPTR2;
INTPTR1 p1, p2;
INTPTR2 p3, p4;

含义分别为,

声明一个指针变量p1和一个整型变量p2

声明两个指针变量p3、p4

#define INTPTR1 int*
typedef int* INTPTR2;
int a = 1;
int b = 2;
int c = 3;
const INTPTR1 p1 = &a;
const INTPTR2 p2 = &b;
INTPTR2 const p3 = &c;

        const INTPTR1 p1是一个常量指针,即不可以通过p1去修改p1指向的内容,但是p1可以指向其他内容。

        const INTPTR2 p2是一个指针常量,不可使p2再指向其他内容。因为INTPTR2表示一个指针类型,因此用const限定,表示封锁了这个指针类型。

        INTPTR2 const p3是一个指针常量。

国嵌八:

符号的技巧:

 那些注释是对的?

#include <stdio.h>
int main()
{int/*...*/i;char* s = "abcdefgh //hijklmn";//一个右斜杠为换行符//Is it a \valid comment?in/*...*/t i;return 0;
}

运行结果:

  • 提示in/*...*/t i;中in未命名;分析:int/*...*/i; 编译器对注释的处理是用空格代替(int i)
  • char* s = "abcdefgh //hijklmn"; 注释符号不能出现在“”之间
  • //Is it a \      valid comment?   一个右斜杠为换行符

注释规则:

  • 编译器会在编译的时候删除掉注释,但不是简单的删除而是用空格代替;
  • 编译器认为双引号括起来的内容都是字符串,//也包括;
  • “/*....*/”型注释不能被嵌套。     

你觉得y=x/*p是什么意思?作者本意:把x除以*p的结果赋值给y。

        编译器:将/*作为一段注释的开始,把/* 后面的内容都当成注释内容,直到*/出现为止。在编译器看来,注释和其它程序元素是平等的,因此,作为工程师不能轻视注释,可以用x/ *p表示(空格的重要性)

  • 注释应该准确易懂,防止二义性,错误的注释有害而无利;
  • 注释是对代码的提示,避免出现臃肿和喧宾夺主;
  • 一目了然的代码避免加注释;
  • 不要用缩写来注释代码,这样可以产生误解;
  • 注释要阐述原因而不是用来描述程序的运行过程。

国嵌九:

接续符和转义符:

#include <stdio.h>
#def\
ine MAX\
255
int main()
{
/\
/这是\
\
注释
i\
n\
t\*\p\
= \NULL;
printf("%0X\n", p);    
return 0;
}

0

C语言中的接续符(\)是指示编译器行为的利器。

接续符的使用:

  • 编译器会将反斜杠剔除,跟在反斜杠后面的字符自动解到前一行;
  • 在接续单词时,反斜杠后不能有空格,反斜杠的下一行之前也不能有空格;
  • 接续符适合在定义宏代码块时使用
#include <stdio.h>
#define SWAP(a,b) \
{                 \int temp = a; \a = b;        \b = temp;     \
}
int main()
{int a = 1;int b = 2;    SWAP(a,b);printf("a=%d, b=%d\n", a, b);return 0;
}

a=2  b=1

C语言中的转义字符(\)主要用于表示无回显字符,也可以用于表示常规字符:

  • C语言中的反斜杠同时具有接续符he转义字符的作用
  • 当反斜杠作为接续符使用时可以直接出现在程序中,
  • 当反斜杠作为转义符使用时需要出现在字符或者字符串中。

国嵌十:

单引号与双引号:

#include <stdio.h>
int main()
{char* p1 = 1 ;char* p2 = '1';char* p3 = "1";printf("%s, %s, %s", p1, p2, p3);printf('\n');printf("\n");return 0;
}

运行结果:提示段错误

分析原因:

  • char* p1 =1 ;表示将p1这个指针空间赋值1,那么p1指向了地址为1的内存空间;
  • char* p2='1';将‘1’对应的ASCLL码(49)赋值给p2指针空间,则p2指向了地址为49的内存空间。这两个地址空间的内存段,都是低地址段,是系统预留的空间,用来拷贝内核代码的使用的,所以上层的应用程序,不能占用这部分空间——段错误
  • char* p3="1";p3是指针空间,分配四个字节大小的空间,用来存放地址值,p3指向的内存空间是char类型的,只分配一个字节空间。char* p3="1";此时p3空间存放的值是字符:‘1’和‘\0’。
  • printf('\n');由printf函数的原型:printf的第一个参数是一个指针类型的形参,那么将一个字符赋值该变量,出现的问题如上述2。

c语言中的单引号和双引号:

  • 单引号:表示字符常量,‘a’表示字符常量;在内存中占一个字节;‘a’+1表示‘a’的ASCLL码+1,结果为‘b’。
  • 双引号:表示字符串常量,“a”表示字符串常量;在内存中占两个字节;“a”+1表示指针运算,结果指向“a”的结束符‘\0’。
#include <stdio.h>
int main()
{char c = " ";while( c=="\t" || c==" " || c=="\n" ){scanf("%c", &c);}return 0;
}

本意:输入\t 空格;输入回车会一直循环while;输入其他字符就会退出while。

运行结果:没有循环

分析原因:

        将字符串赋值给一个字符将发生:字符串存在内存的某个区域,char c = " ";代表的是内存的地址。假如c=0xAABBCCDD,编译器认为是合理的,但是将c转换成c=0xDD;与判断 while( c=="\t" || c==" " || c=="\n" )相比较不会存在相等,即while语句不执行。

更改:

#include <stdio.h>
int main()
{char c = ' ';while( c=='\t' || c==' ' || c=='\n' ){scanf("%c", &c);}return 0;
}

        字符串表示的是字符串的首地址,所以:char abc ="a";实际上abc中存放的是“a”首地址的一个字节的内容(高地址位字节/低地址位字节)。

  • 本质上单括号括起来的一个字符代表整数;
  • 双引号括起来的字符代表一个指针;
  • C编译器接受字符和字符串的比较,可是意义是错误的;
  • C编译器允许字符串对字符变量赋值,可是意义是可笑的。


http://chatgpt.dhexx.cn/article/6XwZ7h5T.shtml

相关文章

【嵌入式】

一.进制转换&#xff1a;分别有以下前缀&#xff0c;2进制常用0B表示&#xff0c;8进制常用0O&#xff0c;16进制常用0X表示&#xff1b;1位八进制数等于3位二进制数&#xff0c;1位十六进制数等于4位二进制数&#xff0c;在二进制转化为八&#xff0c;十六进制数时。如果位数不…

关于嵌入式系统

说实话&#xff0c;笔者是对嵌入式有兴趣的&#xff0c;为什么&#xff0c;因为对于我这样的懒人&#xff0c;是希望以后出去找个稳定的工作&#xff0c;随着年龄的增长工资越高&#xff0c;经验越多&#xff0c;就越吃香&#xff0c;而不是当个最底层的码农&#xff0c;35岁之…

国嵌,够欠!---ARM在线教育误区

大家好&#xff0c;先自我介绍一下&#xff0c;我是国嵌学院的一个很普通的学员&#xff0c;因为应届生不好找工作&#xff0c;去培训机构培训又和上课时间冲突&#xff0c;所以选择了自主学习。在机缘巧合之下&#xff0c;购买了国嵌学院的嵌入式Linux开发课程&#xff0c;在此…

国嵌C语言总结(1-5)

国嵌一&#xff1a; 什么是数据类型&#xff1f; 数据类型是固定内存大小的别名&#xff0c;是创建变量的模子&#xff1b; 变量的本质&#xff1f; 变量是一段实际连续存储空间的别名&#xff1b;程序通过变量来申请并命名存储空间&#xff1b;通过变量的名字可以使用存储空…

使用新版IDEA创建JavaWeb项目详细图文教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 示例概述 三月中下旬了&#xff0c;答辩的日子也越来越近了。之前忙于考研的童鞋&#xff0c;之前忙着玩的童鞋&#xff0c;之前忘记做毕业设计的童鞋都开始忙碌起来了。奈…

idea2022创建javaweb项目

idea版本2022 1.2 //记录一下javaweb的创建 ​​​​​​ name项目名称 location存储地址 Application server&#xff1a;选择new 选中Tomact service 点击下一步 点击下一步就创建成功了

idea创建一个javaweb项目

前提 java环境以及tomcat的安装 1、IDEA创建Web项目 此处以Idea 2020.3.4举例 1、新建普通Java项目 注意&#xff1a;Idea2020无法直接新建JavaWeb项目&#xff0c;只能通过新建普通Java项目的方式间接新建JavaWeb项目。 选择项目位置和普通Java项目相同&#xff0c;此处略过…

java web项目_一个完整JavaWeb项目开发总结

一个JavaWeb项目开发总结 曾经&#xff0c;我跟朋友说我要去学Java&#xff0c;到现在1个月&#xff0c;我总算是七拼八凑的写出了我人生中的第一个Javaweb项目&#xff0c;虽然只是一次简单的爬虫&#xff0c;但是却也更坚定了我学Java的决心 就手写一份我做这次Javaweb项目得…

Linux服务器部署JavaWeb项目

目录 1.搭建JavaWeb环境1.1 安装Java环境1.2 安装 MySQL1.2.1 下载并安装 MySQL1.2.2 启动 MySQL 服务1.2.3 查看 MySQL 默认密码1.2.4 登录 MySQL1.2.5 修改密码1.2.6 为root赋值远程管理权限1.2.7 退出服务器测试 MySQL 连接1.3 安装 Tomcat 2.部署JavaWeb项目2.1 将项目打包…

javaweb项目的文件结构

javaweb项目的文件结构 1、前言 最近使用Intellij idea搭建一个springmvc的web项目时&#xff0c;突然发现&#xff0c;自己好像对web项目的文件结构不是很清晰&#xff0c;对于项目中应该有那些文件夹、文件夹里面又是怎么的文件、他们的作用又是什么&#xff1f;这些好像有点…

JavaWeb项目打包运行

简单记录下JavaWeb项目打包运行 文章目录 项目打包tomcat运行项目 一、项目打包 1.选择out输入目录路径 这里我们可以新建一个文件夹 然后选择 项目打包完就在这个目录底下 2.创建一个工件 3.这里的Name默认的是unnamed 这个 我们这里修改成项目名称 先选择output ro…

JavaWeb项目的热部署配置

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 热部署概述 我们通常期望&#xff1a;修改页面和Java代码后不用重新手动部署项目就可即刻生效&#xff1b;这就是最理想的热部署。然而&#xff1b;理想有多丰满&#xff0…

161个Javaweb项目免费

161个javaweb’项目加qq群&#xff08;105613691&#xff09;自取。网上一些假货我当时找半天找不到费事而且贼生气。现在分享出 如下 <% page language"java" pageEncoding"utf-8"%> <%String path request.getContextPath();String basePat…

JavaWeb项目结构使用Vue项目

提示&#xff1a;javaweb项目中引用Vue项目的案例 文章目录 前言一、JavaWeb项目结构项目启动顺序 二、Vue项目结构Vue结构粗略解释思考 三、使用Vue1、使用vue.js, 在html引用2、使用webpack 构建Vue脚手架第一步&#xff1a; 到webapp包下&#xff0c;输入命令 npm init -y第…

JavaWeb项目结构

4.1 web结构 必需严格按照一种规范来完成 咱们要开发Javaweb的程序,必需要严格参照javaweb提供的一个规范来存放我们的资源…… 结果分析如下: 注意:WEB-INF里面的程序是不可见的,必需通过我们的程序访问 现在:web.xml都不是必需的(但是我们要求必需留着)–这个web.xml可…

eclipse部署Javaweb项目

目录 0.安装Tomcat1.配置Eclipse项目的Tomcat Server2.导入Java Web项目3.设置Tomcat4.配置数据库5.运行项目 0.安装Tomcat 请自行百度搜索如何安装Tomcat&#xff0c;每个项目对Tomcat的版本要求不同&#xff0c;安装之前自行查询你的项目所需要的Tomcat版本。 1.配置Eclips…

linux 部署Javaweb项目

目录 一、配置Java环境1.正确开启linux镜像服务器 二、配置MySQL环境 三、运行Java项目1.在/opt/soft目录下找到apache-tomcat-8.5.81.tar.gz文件并解压 一、配置Java环境 1.正确开启linux镜像服务器 2.正确通过xshell工具链接linux镜像服务器 ip a 3.关闭防火墙 systemct…

IDEA 导入别人的javaweb项目进行部署

前言 我主要是进行java的springboot项目和vue项目的开发&#xff0c;但是架不住在这些框架兴起之前&#xff0c;公司内部已经是有其他的老的框架&#xff0c;我需要在这些老的框架进行修改和调整代码。原本我是使用的eclipse软件进行部署&#xff0c;也比较简单&#xff1b; …

eclipse导入javaWeb项目

eclipse如何正确导入web项目&#xff0c;参考视频&#xff1a;https://www.bilibili.com/video/BV1tV411x7Fb?spm_id_from333.337.search-card.all.click&vd_source825d3d7ea7fd6488824d9e1ce89f8716 二、我遇到的问题 Target runtime Apache Tomcat v7.0 is …

Javaweb项目报告

项目名称&#xff1a;学生考勤系统 主要功能&#xff1a;添加、删除、修改、查询 数据库字段&#xff1a; DROP DATABASE IF EXISTS AttDB; CREATE DATABASE AttDB CHARACTER SET utf8; USE AttDB;CREATE TABLE Student(sid INT PRIMARY KEY AUTO_INCREMENT COMMENT 学号,sn…