【C语言】

news2024/11/16 11:30:31

C语言

  • 1. C语言基础
    • 1.1 数据类型和占位符
    • 1.2 异或
    • 1.3 关键字
    • 1.4 const
    • 1.5 extern
    • 1.6 typedef
    • 1.7 static
    • 1.8 左值和右值
    • 1.9 位进行操作赋值
  • 2. C指针
  • 3. 二维数组和指针
  • 4. 函数传递二维数组
    • 4.1 形参给出第二维的长度。
    • 4.2 形参声明为指向数组的指针。
    • 4.3 形参声明为指针的指针。
  • 5. 二级指针传参数
    • 5.1 二级指针传参数,没有改变原始值
    • 5.2 二级指针传参数,改变原始值
  • 6 数组指针(也称行指针)
  • 7 指针数组
  • 8 指针变量
  • 9 函数指针&指针函数
    • 9.1 指针函数
    • 9.2 函数指针
  • 10 三维数组的传递
  • 11 计算公式最大值最小值和中间值

1. C语言基础

1.1 数据类型和占位符

在这里插入图片描述
在这里插入图片描述

1.2 异或

原则:110000101.
作用:交换两个整数的值而不必用第三个参数
a = 9;
b = 11;
a=a^b;  1001^1011=0010
b=b^a;  1011^0010=1001
a=a^b;  0010^1001=1011

1.3 关键字

设置表格对齐方式:

关键字描述
__asm用于内嵌汇编代码和直接访问底层硬件
__inline用于内联函数,以减少函数调用的开销
attribute用于定义变量或函数的属性,例如对齐方式、可见性、优化等级等
__packed用于取消结构体成员的对齐,以节省内存空间
__irq, __fiq用于定义中断服务函数的类型,以区分普通函数和中断函数
register用于将变量声明为寄存器变量,以提高访问速度
volatile告诉编译器该变量可能会被意外修改,从而避免编译器对该变量进行优化
__weak, __strong用于声明弱引用和强引用变量,在链接时进行符号重定向
__packed, attribute((aligned(n)))用于控制结构体和变量的对齐方式
ARM_ARCH_XX用于条件编译,根据处理器的不同选择不同的代码路径

1.4 const

请看下面三种定义:
const char p; const 修饰的是p 所以是p值不能更改。
char const p; const 修饰的是p 所以是
p值不能更改。
char * const p; const 修饰的是p 所以是p指针不能更改。

1.5 extern

在这里插入图片描述

1.6 typedef

作用是为一种数据类型定义一个新的名字。对于以上两种结构体定义形式,
typedef都可以为其创建别名。

1. 先定义结构体类型,再定义结构体变量
struct student{
    char no[20];      //学号
    char name[20];    //姓名
    char sex[5];      //性别
    int age;          //年龄
};             
struct student stu1,stu2;
//此时stu1,stu2为student结构体变量

2. 定义结构体类型的同时定义结构体变量。
struct student{
    char no[20];        //学号
    char name[20];      //姓名
    char sex[5];        //性别
    int age;            //年龄
} stu1,stu2;      
此时还可以继续定义student结构体变量如:
struct student stu3;

1. 先定义结构体类型,再定义结构体变量
struct{
    char no[20];      //学号
    char name[20];    //姓名
    char sex[5];      //性别
    int age;          //年龄
} stu1,stu2;

1.7 static

在这里插入图片描述

1.8 左值和右值

在这里插入图片描述

1.9 位进行操作赋值

可以对 u16Bit;数据类型中的每个位进行操作赋值,u16Bit.b1 = 1;。

typedef struct{                        
    union{
    struct {
      uint8_t b0:1;            
          uint8_t b1:1;            
          uint8_t b2:1;            
          uint8_t b3:1;            
          uint8_t b4:1;            
          uint8_t b5:1;            
          uint8_t b6:1;                
          uint8_t b7:1;
          uint8_t b8:1;            
          uint8_t b9:1;            
          uint8_t b10:1;            
          uint8_t b11:1;            
          uint8_t b12:1;            
          uint8_t b13:1;            
          uint8_t b14:1;                
          uint8_t b15:1;    
      };
      uint16_t byte;
   };
}u16Bit;

/*********************************定义uint32_t*******************************/
typedef struct {
    uint32_t b0:1;
}u200Bit;

u200Bit u200bit_t;
u200bit_t.b0=1;//赋值
qDebug() << "sizeof(u200Bit)=" << sizeof(u200Bit) << u200bit_t.b0 << endl; //sizeof(u200Bit)= 4 1 

 /*********************************定义uint16_t*******************************/
typedef struct {
    uint16_t b0:1;
}u200Bit;

u200Bit u200bit_t;
u200bit_t.b0=1;//赋值
qDebug() << "sizeof(u200Bit)=" << sizeof(u200Bit) << u200bit_t.b0 << endl; //sizeof(u200Bit)= 2 1 

 /*********************************定义uint8_t*******************************/
typedef struct {
    uint8_t b0:1;
}u200Bit;

u200Bit u200bit_t;
u200bit_t.b0=1; //赋值
qDebug() << "sizeof(u200Bit)=" << sizeof(u200Bit) << u200bit_t.b0 << endl;//sizeof(u200Bit)= 1 1 

2. C指针

main()
{
   int a[5]={1,2,3,4,5};
   int *ptr=(int *)(&a+1);
   printf("%d,%d",*(a+1),*(ptr-1));
}
  • &a + 1: 取数组a 的首地址,该地址的值加上sizeof(a) 的值,即&a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。
    (int *)(&a+1): 则是把上一步计算出来的地址,强制转换为int * 类型,赋值给ptr。

  • *(a+1): a,&a 的值是一样的,但意思不一样,a 是数组首元素的首地址,也就是a[0]的首地址,&a 是数组的首地址,a+1 是数组下一元素的首地址,即a[1]的首地址,&a+1 是下一个数组的首地址。所以输出 (ptr-1): 因为ptr 是指向a[5],并且ptr 是int * 类型,所以(ptr-1) 是指向a[4] ,输出5。

在这里插入图片描述

3. 二维数组和指针

在这里插入图片描述

4. 函数传递二维数组

4.1 形参给出第二维的长度。

在这里插入图片描述
在这里插入图片描述

4.2 形参声明为指向数组的指针。

#include <stdio.h>
void func(int n, char*str)[5] )
{
 int i;
 for(i = 0; i < n; i++)
 printf("\nstr[%d] = %s\n", i, str[i]);
}
void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 func(3, str);
}

4.3 形参声明为指针的指针。

#include <stdio.h>
void func(int n, char **str)
{
	int i;
	for(i = 0; i < n; i++)
	printf("\nstr[%d] = %s\n", i, str[i]);
}
void main()
{
	char* p[3];
	char str[][5] = {"abc","def","ghi"};
	p[0] = &str[0][0];
	p[1] = str[1];
	p[2] = str[2];
	func(3, p);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

char* arg[] = {
        "abc",
        "cde",
        "efg",
    };
//这种写法和上面的等价
char* b[3];
b[0] = arg[0];
b[1] = arg[1];
b[2] = arg[2];

int array[][3] = {
        {1, 2, 3},
        {2, 3, 4},
        {3, 4, 5},
    };

int* a[3];

a[0] = array[0];
a[1] = array[1];
a[2] = array[2];

在这里插入图片描述

5. 二级指针传参数

5.1 二级指针传参数,没有改变原始值

在这里插入图片描述

uis@ubuntu:~/text$ gcc zhizheng.c 
uis@ubuntu:~/text$ 
uis@ubuntu:~/text$ ./a.out 
&a=0x7ffe43789e08,&p=0x7ffe43789e0c
pp=0x7ffe43789e08,kk=0x7ffe43789e0c---&pp=0x7ffe43789e10,&kk=0x7ffe43789e18 
x=0x7ffe43789e10,y=0x7ffe43789e18---&x=0x7ffe43789dd8,&y=0x7ffe43789dd0,--- *x=0x7ffe43789e08,*y=0x7ffe43789e0c  
x=0x7ffe43789e10,y=0x7ffe43789e18---&x=0x7ffe43789dd8,&y=0x7ffe43789dd0,--- *x=0x7ffe43789e08,*y=0x7ffe43789e0c  
x=0x7ffe43789e10,y=0x7ffe43789e18---&x=0x7ffe43789dd8,&y=0x7ffe43789dd0,--- *x=0x7ffe43789e0c,*y=0x7ffe43789e0c  
x=0x7ffe43789e10,y=0x7ffe43789e18---&x=0x7ffe43789dd8,&y=0x7ffe43789dd0,--- *x=0x7ffe43789e0c,*y=0x7ffe43789e08  
a = 20 b = 10, a=10,b=20

5.2 二级指针传参数,改变原始值

在这里插入图片描述

uis@ubuntu:~/text$ gcc zhizheng2.c 
uis@ubuntu:~/text$ 
uis@ubuntu:~/text$ ./a.out 
&a=0x7ffc22703778,&p=0x7ffc2270377c
pp=0x7ffc22703778,kk=0x7ffc2270377c---&pp=0x7ffc22703780,&kk=0x7ffc22703788 
x=0x7ffc22703780,y=0x7ffc22703788---&x=0x7ffc22703748,&y=0x7ffc22703740,--- *x=0x7ffc22703778,*y=0x7ffc2270377c  
x=0x7ffc22703780,y=0x7ffc22703788---&x=0x7ffc22703748,&y=0x7ffc22703740,--- *x=0x7ffc22703778,*y=0x7ffc2270377c  
x=0x7ffc22703780,y=0x7ffc22703788---&x=0x7ffc22703748,&y=0x7ffc22703740,--- *x=0x7ffc22703778,*y=0x7ffc2270377c  
x=0x7ffc22703780,y=0x7ffc22703788---&x=0x7ffc22703748,&y=0x7ffc22703740,--- *x=0x7ffc22703778,*y=0x7ffc2270377c  
a = 20 b = 10, a=20,b=10

6 数组指针(也称行指针)

定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

7 指针数组

定义 int *p[n]; 
//这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。

8 指针变量

int *p;
*p = NULL;
同样,我们可以在编译器上调试这两行代码。第一行代码,定义了一个指针变量 p,其指向
的内存里面保存的是 int 类型的数据;但是这时候变量 p 本身的值是多少不得而知,也就是
说现在变量 p 保存的有可能是一个非法的地址。第二行代码,给*p 赋值为 NULL,即给 p
指向的内存赋值为 NULL;但是由于 p 指向的内存可能是非法的,所以调试的时候编译器可
能会报告一个内存访问错误。这样的话,我们可以把上面的代码改写改写,使 p 指向一块合
法的内存:
int i = 10;
int *p = &i;
*p = NULL;
在编译器上调试一下,我们发现 p 指向的内存由原来的 10 变为 0 了;而 p 本身的值, 即内
存地址并没有改变

9 函数指针&指针函数

在这里插入图片描述

9.1 指针函数

在这里插入图片描述
在这里插入图片描述

9.2 函数指针

在这里插入图片描述

10 三维数组的传递

11 计算公式最大值最小值和中间值

最大值
#define MAX(a, b)     (((a) > (b) ) ? (a) : (b))
最小值
#define MIN(a, b)     (((a) < (b) ) ? (a) : (b))
中间值
#define MID(a,b,c)     a>b?(a>c?(b>c?b:c):(a)):(a>c?(a):(b>c?c:b))

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速掌握队列的基础知识

目录 队列的特点基于链表实现队列用栈实现队列用队列实现栈 队列是一种线性数据结构&#xff0c;它只允许在一边进行插入操作&#xff08;队尾&#xff09;&#xff0c;另一边进行删除操作&#xff08;队头&#xff09;。插入操作称为入队&#xff0c;删除操作称为出队。队列遵…

【网络奇缘】我和英特网再续前缘

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络的概念 计算机网络的功能 ⭐1.数据通信 ⭐2.资源共享 ⭐3.分布式处理 ⭐4.提高可靠性 ⭐…

Java17新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…

Eclipse打包Springboot项目

首先&#xff0c;在pom.xml文件中添加配置&#xff0c;修改mainClass主函数&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configurat…

【电路笔记】-戴维南定理(Thevenin‘s Theorem)

戴维南定理&#xff08;Thevenin’s Theorem&#xff09; 文章目录 戴维南定理&#xff08;Thevenins Theorem&#xff09;1、概述与定义2、戴维南模型确定3、一些线性电路的戴维南模型3.1 单电压源3.2 单电流源3.3 多电流/电压源 4、结论 在本文中&#xff0c;我们将介绍一种强…

LLaMA模型之中文词表的蜕变

在目前的开源模型中&#xff0c;LLaMA模型无疑是一颗闪亮的⭐️&#xff0c;但是相对于ChatGLM、BaiChuan等国产大模型&#xff0c;其对于中文的支持能力不是很理想。原版LLaMA模型的词表大小是32K&#xff0c;中文所占token是几百个左右&#xff0c;这将会导致中文的编解码效率…

Python---综合案例:通讯录管理系统---涉及点:列表、字典、死循环

需求&#xff1a; 开个一个通讯录的管理系统&#xff0c;主要用于实现存储班级中同学的信息&#xff08;姓名、年龄、电话&#xff09; 涉及点&#xff1a;列表、字典、死循环 相关链接&#xff1a;Python--列表及其应用场景---增、删、改、查。-CSDN博客 Python---字典---…

ip数据包

数据报文格式 首部 版本&#xff08;Version&#xff09; 版本字段占4bit&#xff0c;通信双方使用的版本必须一致。对于IPv4&#xff0c;字段的值是4。 首部长度&#xff08;Internet Header Length&#xff0c; IHL&#xff09; 占4bit&#xff0c;首部长度说明首部有多少…

ubutun上编译出现undefined reference to symbol ‘dladdr@@GLIBC_2.2.5‘的错误

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> ubutun上编译一段C程序&#xff0c;出现错误&#xff1a; /usr/bin/ld: /tmp/ccghh3FJ.o: undefined reference to symbol ‘dladdrGLIBC_2.2.5’ //lib/…

前端---CSS的盒模型

文章目录 什么是盒模型&#xff1f;设置边框设置内边距设置外边距块级元素水平居中 什么是盒模型&#xff1f; 页面上的每个HTML元素都是一个一个的“盒子”&#xff0c;这些盒子由&#xff1a;内容、内边距、边框、外边距组成。 我们可以和住的房子联系起来&#xff0c;更好…

HarmonyOS开发(二):TypeScript入门

1、编程语言介绍 ArkTS是HarmonyOS主推的应用开发语言&#xff0c;它是在TypeScript语言的基础之上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 ArkTS、TypeScript和JavaScript之间…

打开 Chrome 的 「内存节省程序」开关和关闭硬件加速

不知道从什么时候开始&#xff0c;应该是最近1个月&#xff0c;感觉 Mac 浏览器总是占用很高的 CPU&#xff0c;多开一些标签页&#xff0c;或者浏览器窗口&#xff0c;相互切换时系统就会变得无响应&#xff0c;从 Chrome 浏览器里找到一个「内存节省程序」的配置&#xff0c;…

数据校验:Spring Validation

Spring Validation概述 在开发中&#xff0c;我们经常遇到参数校验的需求&#xff0c;比如用户注册的时候&#xff0c;要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式&#xff0c;我们会把校验的代码和真正的业务处理逻辑耦…

二维码智慧门牌管理系统升级解决方案:运营可视化之道

文章目录 前言一、系统概述二、数据可视化与运营决策 前言 随着科技的飞速发展和人们生活水平的提高&#xff0c;传统的门牌管理系统已经无法满足现代社会的需求。在这个信息化、智能化的时代&#xff0c;一款升级版的二维码智慧门牌管理系统应运而生&#xff0c;它将以全新的…

手机能做静态二维码吗?用手机做二维码的教程

现在手机上有很多的功能&#xff0c;能够帮助我们应对日常生活中的各种问题&#xff0c;那么如果我们想要在手机上生成一个静态二维码&#xff0c;大家知道该怎么来操作吗&#xff1f;一般制作二维码需要专业的二维码生成工具才可以完成制作&#xff0c;那么下面小编来给大家分…

properties文件乱码

出现如下乱码&#xff1a; 按照步骤修改编码方式就可以解决啦 修改之后结果就是下面这样~

【LabVIEW学习】1.对labview的初步使用,控制数据流动

一。初步使用labview 1.程序图标 2.打开之后继续点击新建VI 原因&#xff1a;最后的程序后缀就是 .vi 3.新建之后&#xff0c;会有三个界面&#xff08;没有不要紧&#xff0c;找找肯定有&#xff09; 4.程序操作方法 1.拖动控件到前面板 2.此时程序框图会出现对应的控件 拖动…

利用Python群组分析方法剖析客户行为

大家好&#xff0c;如今的企业有能力收集大量的数据&#xff0c;这些数据可以帮助企业制定更好的策略并了解其客户的行为。Cohort分析可以在其中发挥作用&#xff0c;Cohort分析是一种了解客户行为或用户互动的强大工具&#xff0c;并为企业提供有价值的见解&#xff0c;本文中…

优雅的Java编程:将接口对象作为方法参数

theme: smartblue 目录 概述 在Java编程中&#xff0c;方法的参数传递方式通常是通过基本类型、对象引用或者集合等方式。然而&#xff0c;一种更加优雅且灵活的设计模式是将接口对象作为方法的参数。这种方式为我们带来了许多好处&#xff0c;包括降低耦合性、实现多态性和可…

微信小程序display常用属性和子元素排列方式介绍

wxss中display常用显示属性与css一致&#xff0c;介绍如下&#xff1a; 针对元素本身显示的属性&#xff1a; displayblock&#xff0c;元素显示换行displayinline&#xff0c;元素显示换行&#xff0c;但不可设置固定的宽度和高度&#xff0c;也不可设置上下方向的margin和p…