c语言指针

冒泡排序与指针结合

不羁岁月 提交于 2019-12-20 10:37:34
冒泡与选择排序为C语言排序经典,以下为经典样例,供读者参考 # include <stdio.h> //选择排序 void select ( int a [ ] , int n ) { int i , j ; for ( int j = 1 ; j < n - 2 ; j ++ ) for ( int k = j + 1 ; k < n - 2 ; k ++ ) { if ( a [ j ] > a [ k ] ) //升序 { int t ; t = a [ k ] ; a [ k ] = a [ j ] ; a [ j ] = t ; } } } //冒泡 void pro ( int a [ ] , int n ) { int i , j , k , t ; for ( int j = 1 ; j <= n ; j ++ ) for ( int k = 1 ; k <= n - j ; k ++ ) { if ( a [ k + 1 ] > a [ k ] ) { int t ; t = a [ k ] ; a [ k ] = a [ k + 1 ] ; a [ k + 1 ] = t ; } } } //冒泡的指针算法 void zhizhen ( int * b , int n ) { int i , j , k , * p ; for ( j = 0 ; j <= n

c语言中文件的使用方法

送分小仙女□ 提交于 2019-12-20 08:38:40
c语言中文件的使用方法 一.文件指针的定义 FILE * fp //注意FILE的大写 二.文件的打开 fp = fopen ( "(路径)文件名.文件格式后缀" , "文件的使用方法" ) //注意路径下为//而不是/ 三.文件的使用方法 1.“r” 模式: 1.1 打开文件进行只读操作,即只能从文件读取内容。 1.2 若欲操作的文件不存在,则打开失败。 1.3 成功打开文件时,文件指针位于文件开头。 1.4 打开文件后,不会清空文件内原有内容。 1.5 可从文件中任意位置读取内容。 2."w" 模式: 2.1 打开文件进行“只写”操作,即只能向文件写入内容。 2.2 若欲操作的文件不存在,则新建文件。 2.3 成功打开文件时,文件指针位于文件开头。 2.4 打开文件后,会清空文件内原有的内容。 2.5 可向文件中任意位置写入内容,且进行写入操作时,会覆盖原有位置的内容。 3."a" 模式: 3.1 打开文件进行“追加”操作,即只能向文件写入内容。 3.2 若欲操作的文件不存在,则新建文件。 3.3 成功打开文件时,文件指针位于文件结尾。 3.4 打开文件后,不会清空文件内原有内容。 3.5 只能向文件末尾追加(写)内容。 4."r+"模式: 4.1 打开文件进行“读写”操作,即既可读取,又可写入。 4.2 若欲操作的文件不存在,则打开失败。 4.3 成功打开文件时

2019年12月18日-关于void *

岁酱吖の 提交于 2019-12-19 07:32:14
说到C就不得不提指针,指针和结构体两个东西是C语言的灵魂。而一提到指针,有一个比较特殊的,那就是void*。void*到底是怎样的存在? 指针类型的含义 在说明void*之前,先了解一下普通指针类型的含义。 # include <stdio.h> # include <stdlib.h> int main ( ) { int a [ ] = { 0x01020304 , 2019 } ; int * b = a ; char * c = ( char * ) & a [ 0 ] ; printf ( "b+1:%d\n" , * ( b + 1 ) ) ; printf ( "c+1:%d\n" , * ( c + 1 ) ) ; system ( "pause" ) ; return 0 ; } 输出结果为 同样是指针类型,b和c有什么区别? 一个是指向整型的指针,一个是指向char型的指针,当它们执行算术运算时, 它们的步长就是对应类型占用空间大小 。 结论 :各种类型的指针没有本质区别,只是解释内存中的数据方式不同。例如,对于int型指针b,该引用时,会解析4字节,算术运算时,也是以该类型占用空间大小为单位。所以b+1,移动4字节,解引用,处理4字节内容,得到2019。对于char型指针C,解引用时,会解析1个字节,算术运算时,也是以sizeof(char)为单位,所以c+1

C语言第八讲,指针*

人盡茶涼 提交于 2019-12-19 00:33:58
            C语言第八讲,指针* 一丶简单理解指针 说到指针,很多人都说是C语言的重点. 也说是C语言的难点. 其实指针并不是难.而是很多人搞不清地址 和 值.以及指针类型. 为什么这样说. 假设有两个变量,如下 int nNum1 = 1; int nNum2 = 0x00401000; 变量nNum1 保存的值是1 变量nNum2 保存的是一个16进制数值. 那么如果我们把保存16进制的这个变量.当作指针. 也就是说它保存了一个16进制数值而已. 我们可以通过16进制找到里面存储的值. 但是因为是保存地址的变量.所以我们需要加上特殊符号进行定义. 例如:    int *nNum2 = 0x004010000; 指针其实就是保存了一个特殊的数值而已. 而通常这个数值我们说是地址. 如果我们保存了1的地址,那么我们就可以访问1了. 怎么访问? 可以通过取内容符号进行访问. int nNum = 1; int *p = &nNum1; //保存1的地址,我们可以不用管.也可以理解为一个16进制数值而已. *p = 3; //修改地址空间的值. 二丶指针的数据类型 说到指针.其实我们说的并不是保存地址的难点.难点是该如何解释这个地址. 例如我们知道定义一个变量.我们可以知道这个变量的内存空间跟随这数据类型走. 例如:    int nNum1 = 3; //nNum1

C指针右左法则

荒凉一梦 提交于 2019-12-18 21:32:22
摘录的别人的: C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的: The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed. 这段英文的翻译如下: 右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。 笔者要对这个法则进行一个小小的修正

C++ ------ 引用

痴心易碎 提交于 2019-12-18 21:15:35
一、引用简介   引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。   引用的声明方法:类型标识符 &引用名=目标变量名;   【例1】:int a; int &ra=a; //定义引用ra,它是变量a的引用,即别名   说明:   (1)&在此不是求地址运算,而是起标识作用。   (2)类型标识符是指目标变量的类型。   (3)声明引用时,必须同时对其进行初始化。   (4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。    ra=1; 等价于 a=1;   (5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。   (6)不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。 二、引用应用 1、引用作为参数   引用的一个重要作用就是作为函数的参数。以前的C语言中函数参数传递是值传递,如果有大块数据作为参数传递的时候,采用的方案往往是指针,因为 这样可以避免将整块数据全部压栈,可以提高程序的效率。但是现在(C++中)又增加了一种同样有效率的选择(在某些特殊情况下又是必须的选择),就是引 用。  

环形缓冲区的应用ringbuffer

爷,独闯天下 提交于 2019-12-18 01:59:35
在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法, 当读取速度大于写入速度时 ,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外)。 在通信程序中,经常使用环形缓冲区作为 数据结构 来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。 1、环形缓冲区的实现原理 环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。 图 1、图 2 和图 3 是一个环形缓冲区的运行示意图。 图1 初始状态 图二 向环形缓冲区中添加了一个数据 图三环形缓冲区进行了读取和添加 图 1 是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处; 图 2 是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块 2 的位置,而读指针没有移动; 图 3 是环形缓冲区进行了读取和添加后的状态,可以看到环形缓 冲区中已经添加了两个数据

C语言指针(五)--函数指针

夙愿已清 提交于 2019-12-17 05:49:33
在第四篇关于链表的文章中读者可以通过实现单向链表了解简单的指针应用。但是,在这之中出现了函数指针和空指针。在这篇文章中将对这两方面的内容做讨论。 说实话我现在我快崩溃了,这是我第三遍写这篇文章,前两遍都是在我正要发布的时候莫名其妙的没有啦。所以。。。。。。先提三个问题 1.定义一个函数指针,返回值为int参数为空。 2.定义一个函数指针,返回值int参数为int。 3.定义一个返回int指针的函数参数为int。 4.定义一个返回函数指针的函数参数为空,返回的函数指针参数和返回值都是int。 对于C语言基础较好的读者,前两个问题应该不成问题,但是第三个问题就不是所有读者都可以搞定了。 1. int ( * fun ) ( void ) ; 2 int ( * fun ) ( int ) ; 3. int * fun ( int prg ) { } 4. ? 我们观察前两个问题的答案,可能会发现函数指针的定义其实就是在函数定义的基础之上把函数名用括号括起来然后在函数名前加一个星号。 所以第四个问题的答案可能是这样的 int ( * fun ) ( int ) function ( void ) { } 可是我们观察第四个问题答案发现返回的指针并没有指针名所以应该把上面的定义改写成这样 int ( * fun ( void ) ) ( int ) {} 至于为什么是这样而不是这样 int

C语言博客作业06--结构体&文件

别说谁变了你拦得住时间么 提交于 2019-12-16 13:53:17
1.本章学习总结 1.1 学习内容总结 1.结构的介绍 结构(Structure)类型是一种允许程序员把一些数据分量聚合成一个整体的数据类型,一个结构中包含的每个数据分量都有名字。这些数据分量称为结构成员或者结构分量,结构成员可以是C语言中的任意变量类型,程序员可以使用结构类型来创建适合于问题的数据聚合。 像数组和指针一样,结构也是一种构造数据类型(或叫派生数据类型),它与数组的区别在于:数组中所有元素的数据类型必须是相同的,而结构中各成员的数据类型可以不同。 2.结构是C语言中一种新的构造数据类型,它能够把有内在联系的不同类型的数据汇聚成一个整体,使它们相互关联;同时,结构又是一个变量的集合, 可以按照对基本数据类型的操作方达单独使用其成员变量。 3.在C语言中,整型、实型等基本数据类型是被系统预先定义好了的,程序员可以用其直接定义变量。而结构类型是由用户根据需要,按规定的格式自行定义的数据类型。 4.结构类型定义的一般形式为: struct 结构名 { 类型名 结构成员名1; 类型名 结构成员名2; … 类型名 结构成员名n; }; 5.struct是定义结构类型的关量字,在struct之后,自行命名一个结构名,它必须是一个合法的C标识符。struct与结构名两者合起来共同组成结构类型名,大括号内的内容是结构所包括的结构成员,也叫结构分量。结构成员可以有多个,这样

C语言--传值与传指针

人盡茶涼 提交于 2019-12-16 04:44:53
我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。 传值 我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的: #include<stdio.h> void swap(int a,int b) { int temp = a; a = b; b = temp; printf("internal swap a = %d,b = %d\n",a,b); } int main(void) { int a = 10; int b = 20; printf("before swap:a = %d,b = %d\n",a,b); swap(a,b); printf("after swap:a = %d,b = %d\n",a,b); return 0; } 结果如下: before swap:a = 10,b = 20 internal swap a = 20,b = 10 after swap:a = 10,b = 20 为什么呢?因为函数参数在传递的时候,都是 传原数据的副本** ,也就是说,swap内部使用的a和b只是最初始a和b的一个副本而已,所以无论在swap函数内部对a和b做任何改变,都不会影响初始的a和b的值。 正因如此,我们常常被告知,不要把直接把结构体直接作为参数