c语言指针

C语言函数指针的用法

丶灬走出姿态 提交于 2020-01-31 06:01:28
这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址: http://www.cnblogs.com/archimedes/p/function-pointer-in-c-struct.html ,转载请注明源地址。 引言 指针是C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序。我们要记住指针是一个指向内存地址的变量。指针可以引用如int、char……常见的数据类型,例如: int * intptr; // 声明一个指向整型值的指针 int intval = 5 ; // 定义一个整型变量 intptr = & intval ; // intptr现在包含intval的地址 指针不仅仅指向常规的类型还可以指向函数 函数指针 函数指针的内容不难理解,不再赘述,参见《 C语言函数指针的用法 》 语法 要声明一个函数指针,使用下面的语法: Return Type ( * function pointer's variable name ) ( parameters ) 例如声明一个名为func的函数指针,接收两个整型参数并且返回一个整型值 int (*func)(int a , int b ) ; 可以方便的使用类型定义运用于函数指针: typedef int (*func)(int a , int b ) ;

结构体中定义函数指针

做~自己de王妃 提交于 2020-01-30 11:10:10
结构体指针变量的定义 定义结构体变量的一般形式如下: 形式1:先定义结构体类型,再定义变量 struct 结构体标识符 {   成员变量列表;… }; struct 结构体标识符 *指针变量名; 变量初始化:struct 结构体标识符 变量名={初始化值1,初始化值2,…,初始化值n }; 形式2:在定义类型的同时定义变量 struct 结构体标识符 {   成员变量列表;… } *指针变量名; 形式3:直接定义变量,用无名结构体直接定义变量只能一次 struct {   成员变量列表;… }*指针变量名; 其中“指针变量名”为结构体指针变量的名称。形式1是先定义结构体,然后再定义此类型的结构体指针变量;形式2和形式3是在定义结构体的同时定义此类型的结构体指针变量。 函数指针的定义 一般的函数指针可以这么定义:    int (*func)(int,int); 表示一个指向含有两个int参数并且返回值是int形式的任何一个函数指针. 假如存在这样的一个函数: int add2(int x,int y) {   return x+y; } 那么在实际使用指针func时可以这样实现: func=&add2; //指针赋值,或者func=add2; add2与&add2意义相同 printf("func(3,4)=%d\n",func(3,4)); 事实上,为了代码的移植考虑

ctypes给扩展模块中的函数传递数组和结构体

大城市里の小女人 提交于 2020-01-30 02:56:27
传递数组 楔子 下面我们来看看如何使用ctypes传递数组,这里我们只讲传递,不讲返回。因为C语言返回数组给python实际上会存在很多问题,比如:返回的数组的内存由谁来管理,不用了之后空间由谁来释放,事实上ctypes内部对于返回数组支持的也不是很好。因此我们一般不会向python返回一个C语言中的数组,因为C语言中的数组传递给python涉及到效率的问题,python中的列表传递直接传递一个引用即可,但是C语言中的数组过来肯定是要拷贝一份的,所以这里我们只讲python如何通过ctypes给扩展模块传递数组,不会介绍扩展模块如何返回数组给python。 如何传递 我们知道python中没有数组,或者说C中的数组在python中是一个list,我们可以通过list来得到数组,方式也很简单。 from ctypes import * # 创建一个数组,假设叫[1, 2, 3, 4, 5] a5 = (c_int * 5)(1, 2, 3, 4, 5) print(a5) # <__main__.c_long_Array_5 object at 0x00000162428968C0> # 上面这种方式就得到了一个数组 # 当然还可以使用list a5 = (c_int * 5)(*range(1, 6)) print(a5) # <__main__.c_long_Array_5

无类型指针、空指针和野指针

笑着哭i 提交于 2020-01-29 17:57:49
1、无类型指针:void *p; 不指定它指向具体哪种数据类型。可以通过强制转化将void *转化为其他类型指针,也可以用(void *)将其他类型指针强制转化为void类型指针。指针之间赋值需要类型相同,但任何类型的指针都可以赋值给void *。 2、空指针:NULL NULL在C语言中的定义为(void *)0。空指针就是指向了NULL的指针变量。如果一个指针不能确定指向任何一个变量的地址,应将这个指针设置为空指针。 3、野指针 野指针,没有指向任何有效地址的指针变量,所以在代码中避免出现野指针。 来源: CSDN 作者: 星尘亦星辰 链接: https://blog.csdn.net/Mrweng1996/article/details/104106415

c/c++常见面试题一

╄→гoц情女王★ 提交于 2020-01-29 04:04:13
找工作这么多天了,贴一下常见基础题吧,谁找工作了还可以复习下。答案有的是缺少很多,想看全百度之谷歌之... 1.进程与线程的区别:   很长重点写了:一个程序必须有一个进程,一个进程要有一个线程。   进程在运行时有独立的内存单元,而线程则是共享内存单元,所以一个线程死掉这个进程就会死掉,但是一个进程死掉程序无所谓。所以多进程程序比多线程要      稳定。   2.c++函数传递参数的方式:   1.直接传递、引用、指针。   他们的优缺点:   1.按值传递,在传递的时候实参被复制了一份,然后在函数体内使用。如果修改函数体内的拷贝,而实参是没有改变的。   2.引用是别名,所以效率别指针快,也比指针安全。(优先使用引用而不使用指针)   3.按值传递和引用传递在传参过程中,都执行强类型检查,而指针传递的类型比较弱,如果参数被声明为void*基本上没有类型检查,只要是指针编译器就认为是合法的,所以这会造成BUG。   4.指针可以干引用的活,而且还可以传递空指针,特别函数特别应用。但是指针用起来本身就很麻烦,如非需要还是不用。 *3.什么是深拷贝和浅拷贝    深拷贝:拷贝了对象的资源,在新对象中又建立了一个新的字段把资源放进去,如果修改其一,另一个不会改变。    浅拷贝:没有拷贝对象资源,它们共享资源,如果改变其一另一个也会随之改变。 4.面向对象的三个基本特征   1)封装

C:指针基础

夙愿已清 提交于 2020-01-29 01:18:03
内存概述 内存 内存含义: 存储器:计算机的组成中,用来存储程序和数据,辅助CPU进行运算处理的重要部分。 内存:内部存贮器,暂存程序/数据——掉电丢失 SRAM、DRAM、DDR、DDR2、DDR3。 外存:外部存储器,长时间保存程序/数据—掉电不丢ROM、ERRROM、FLASH(NAND、NOR)、硬盘、光盘。 内存是沟通CPU与硬盘的桥梁: 暂存放CPU中的运算数据 暂存与硬盘等外部存储器交换的数据 物理存储器和存储地址空间 有关内存的两个概念:物理存储器和存储地址空间。 物理存储器:实际存在的具体存储器芯片。 主板上装插的内存条 显示卡上的显示RAM芯片 各种适配卡上的RAM芯片和ROM芯片 存储地址空间:对存储器编码的范围。我们在软件上常说的内存是指这一层含义。 编码:对每个物理存储单元(一个字节)分配一个号码 寻址:可以根据分配的号码找到相应的存储单元,完成数据的读写 内存地址 将内存抽象成一个很大的一维字符数组。 编码就是对内存的每一个字节分配一个32位或64位的编号(与32位或者64位处理器相关)。 这个内存编号我们称之为内存地址。 内存中的每一个数据都会分配相应的地址: char:占一个字节分配一个地址 int: 占四个字节分配四个地址 float、struct、函数、数组等 指针基础 指针和指针变量 内存区的每一个字节都有一个编号,这就是“地址”。

C语言基础三之指针一

丶灬走出姿态 提交于 2020-01-29 00:18:49
空指针 野指针 万能指针 int *p = NULL; int a =1000; p = &a; void* xx = p; *(int*)p = 1000000; printf("%d \n",*p); const 修饰指针 const int a = 10; int b = 100; //第一种 int *p = &a; p = &b; (V) *p = 1000; (V) //第二种 const int *p = &a; p = &b; (V) *p = 1000; (X) //第三种 int * const p = &a; p = &b; (X) *p = 1000; (V) //第四种 const int * const p = &a; p = &b; (X) *p = 1000; (X) 指针数组 char* arr[] = {"aaaa","bbbb","cccc"}; arr[0]表示"aaaa"的地址值 *(arr[0]+1) 表示“aaaa”中第二个元素的值 []的优先级高 ,是的char* arr[]的本质是 一个数组,数组的元素为指针类型 数组指针 char hello[] = {"hello world"}; char (*pHello)[] = &hello; pHello是一个指针类型,指向的元素为char[] 指针做参数和返回值

最全面的C/C++编码规范总结

牧云@^-^@ 提交于 2020-01-28 20:02:33
C语言是面向过程的,而C++是面向对象的 对于不同的编程语言来说,具体的编码规范可以有很大的不同,但是其宗旨都是一致的,就是保证代码在高质量完成需求的同时具备良好的可读性、可维护性。例如我们可以规定某个项目的C语言程序要遵循这样的规定:变量的命名,头文件的书写和#include 等等。 下面是一些广为采用的编码规范: GNU Coding Standards Guidelines for the Use of the C Language in Vehicle Based Software C++ Coding Guidelines SUN Code Conventions for Java 以下是一些介绍编码、编码规范的书籍: C++编码规范,陈世忠,人民邮电出版社,2002 高质量程序设计指南:C++/C语言,林锐等,电子工业出版社,2003 注:以下只是根据课题组已有的经验给出的总结,并非对所有场景均适用。 对于高质量的工程,一般会做到: 代码简洁精炼,美观,可读性好,高效率,高复用,可移植性好,高内聚,低耦合,没有冗余,不符合这些原则,必须特别说明。 规范性,代码有规可循。特殊排版、特殊语法、特殊指令,必须特别说明。 小编推荐一个学C语言/C++的学习裙【 二六三,六八八,二七六 】,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有开发工具

c语言指针初探

天大地大妈咪最大 提交于 2020-01-28 17:15:52
与c语言指针相关联的三个符号,一个是地址符&,一个是间接符号*,还有一个是在声明指针时用到的*符号。 那么什么是指针呢?指针时存储变量地址的变量,不是整型,它就像int,float一样是指针类型。 p = & i ; //p存储的是变量i在内存中的地址 i = * p ; //*符号加在指针p前,表示取的是这个地址上的变量值 printf ( "%p" , p ) ; //打印指针使用%p 例子:定义一个函数用于交换两个变量的值 # include <stdio.h> void interchange ( int , int ) ; int main ( void ) { int a = 5 ; int b = 3 ; printf ( "交换前a=%d,b=%d.\n" , a , b ) ; interchange ( a , b ) ; printf ( "交换后a=%d,b=%d.\n" , a , b ) ; return 0 ; } void interchange ( int a , int b ) { int temp ; temp = b ; b = a ; a = temp ; } 程序运行的结果 因为函数内的变量是局部变量,只存在于函数内部,函数interchange里的ab虽然交换了,但这里的ab和主函数的ab没有关联,它们在内存中的地址都不一样

【C语言进阶剖析】42、内存操作的经典问题分析(二)

梦想的初衷 提交于 2020-01-28 17:11:54
1 常见内存错误 结构体成员指针未初始化 结构体成员指针未分配足够的内存 内存分配成功,但未初始化 内存操作越界 我们记得定义一个指针的时候要初始化,却容易忘记定义结构体变量时初始化指针成员。指针未分配足够的内存会导致越界操作的问题。内存分配成功,但未初始化,这个可能回造成字符串方面的错误。内存操作越界可能会操作不因该操作的内存,比如字符串没有结尾的 ‘\0’,复制的时候没有发现结尾的 ‘\0’,导致越界了。第四条包括的 2,3 条。 2 找内存错误 下面我们来找找下面的程序中哪里出现了内存错误呢? // 42-1.c # include <stdio.h> # include <malloc.h> void test ( int * p , int size ) { int i = 0 ; for ( i = 0 ; i < size ; i ++ ) { printf ( "%d\n" , p [ i ] ) ; } free ( p ) ; } void func ( unsigned int size ) { int * p = ( int * ) malloc ( size * sizeof ( int ) ) ; int i = 0 ; if ( size % 2 != 0 ) { return ; } for ( i = 0 ; i < size ; i ++ ) {