c语言指针

如何判断一个变量是指针

我们两清 提交于 2020-01-07 05:17:27
1、面试问题 编写程序判断—个变量是不是指针。 2、指针的判别 拾遗 C++中仍然支持C语言中的可变参数函数 C++编译器的匹配调用优先级 1. 重载函数 2. 函数模板 3. 变参函数 思路 将变量分为两类:指针 vs 非指针 编写函数:指针变量调用时返回true ,非指针变量调用时返回false 函数模板与变参函数的化学反应 template <typename T> bool IsPtr(T* v) // match pointer { return true; } bool IsPtr(...) // match non-pointer { return false; } 编程实验 指针判断 test.cpp #include <iostream> using namespace std; class Test { public: Test() { } virtual ~Test() { } }; template <typename T> bool IsPtr(T* v) // match pointer { return true;} bool IsPtr(...) // match non-pointer {   return false; } int main(int argc, char *argv[]) {   int i = 0;   int* p = &i;

C语言 指针

泄露秘密 提交于 2020-01-05 10:30:34
指针 : 地址 的代名词 , 在32位系统中,指针就4个字节; 指针变量 : 存放指针这个概念的盒子 指针每次读取的数据大小,取决于定义指针的数据类型;(int *p ; char *p) #include "stdio.h" int a=0x213432; int *p1; void main() { p1=&a; printf("%x\n",*p1); }结果:213432 int a=0x213432; char *p1; void main() { p1=&a; printf("%x\n",*p1); }编译会出现警告warning: assignment from incompatible pointer type, 结果为32.    指针+修饰符 const 常量,只读【不能变】 char *p; const char *p; p可以指向任意空间,但不希望改变其中的内容(与char const *p相同 ) char * const p : p一旦被赋值,将永远指向这个地址,但内容可以改变(与 char *p const相同 ) 硬件资源 const char * const p : ROM volatile 防止优化指向内存地址 volatile char *p typedef 别名 指针+运算符 加减运算 指针的加法/减法运算,实际上是增加一个单位

野指针?空指针?

浪子不回头ぞ 提交于 2020-01-05 04:44:56
野 指针指的是指向不可用内存的指针。任何指针变量在被创建时,不会自动成为NULL指针(空指针),其缺省值是随机的,所以,指针变量在创建的同时应当被初始化,或者将指针设置为NULL,或者让它指向合法的内存,而不应该放之不理,否则就会成为野指针 。 而同时由于指针被释放(free或delete)后,未能将其设置为为NULL,也会导致该指针变为野指针。虽然free和delete把指针所指的内存给释放掉了,但它们并没有把指针本身干掉 ,一般可以采用语句if (p != NULL)进行防错处理,但是if语句却起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。第三种造成野指针的原因是指针操作超越了变量的作用范围。 例如如下程序示例。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *p = (char *) malloc(100); strcpy(p, "hello"); free(p); if(p != NULL) printf("Not NULL\n"); return 0; } 输出: Not Null 上例中,虽然对p执行了free操作 , p 所指的内存被释放掉了,但是p所指的地址仍然不变,在后续的判断p是否为NULL时,根本没有起到防错的作用

C语言-----野指针

ε祈祈猫儿з 提交于 2020-01-05 04:39:28
问题所在 1、 局部指针变量没有被初始化 2、 使用已经释放过后的指针 3、 指针所指向的变量在指针之前被销毁 4、 结构体成员指针未初始化, 没有为结构体指针分配足够的内存 ,内存越界(考虑使用柔性数组)和 泄露 避免规则 1、用 malloc 申请了内存之后,应该立即检查指针值是否为 NULL ,防止使用值为 NULL 的指针 2、牢记数组的长度,防止数组越界操作,考虑使用柔性数组 3、动态申请操作必须和释放操作匹配,防止内存泄露和多次释放 4、 free 指针之后必须立即赋值为 NULL malloc用于从堆中分配一块指定大小的内存,以void *的类型返回这块内存的起始地址。malloc的参数就是要分配的内存的大小,以字节为单位。 所以如果要分配1个整型空间就需要malloc(sizeof(int)),由于返回的void *不能直接赋值给int *,所以还要进行一次强制类型转换int * s=(int*)malloc(sizeof(int)); struct Student { char* name; int number; }; int main() { struct Student s; strcpy(s.name, "gggg"); // OOPS! ////////////////////////////////////野指针,,不能随便赋值,因为s是一个局部变量

C语言野指针

坚强是说给别人听的谎言 提交于 2020-01-05 04:37:06
指针是C语言一个很强大的功能。然而所谓成也萧何,败也萧何,用好了指针会使程序大放异彩,用错了指针轻者只是报个错,重者可能整个系统都崩溃了。本篇我们来谈谈指针一种错误的使用方法”野指针“。 野指针一般是指定义时没有给初值的指针变量。来看以下程序: #include <stdio.h> #include <string.h> int main() { char *source1 = "abc"; char *source2; printf("source2的值是:%u\n", source2); strcpy(source2 , source1); printf("%s",source2); return 0; } 这段程序定义了一个指向字符的指针 source2,但是没有给它一个初始值。下面的代码就是将字符串”abc“复制到source2中,编译的结果如下: --------------------Configuration: Test - Win32 Debug-------------------- Compiling... demo.c D:\CCode\Test\demo.c(8) : warning C4700: local variable 'source2' used without having been initialized Linking... Test.exe

C++ 基础知识复习(二)

▼魔方 西西 提交于 2020-01-05 04:24:21
异常处理部分: 23. 在c++的异常处理中,除了提供异常的关键字语法支持以外,其标准库中支持异常处理而封装异常类也很好的为应用程序中异常处理判断使用提供直接的帮助。C++语言中针对异常处理提供了三个关键字,分别为try、throw与catch。C++应用程序中通过这三个关键字实现机制组合来实现异常的处理。try体中可以直接抛出异常,或者在try体中调用的函数体中间接的抛出。注意catch是接thorw出来的数据的,数据类型上要兼容。 预处理及内存管理部分: 24. C语言提供的预处理功能有哪些: 答:宏定义,文件包含和条件编译。 25. include的使用方式: 答:include 如果包含的文件名在尖括号内,则为标准头文件,会在预定义的位置集进行查找。位置集可有环境变量或命令行修改。引号中为自定义头文件,查找始于源文件所在路径,一层层找直到系统文件目录。 26. 如何申请以及释放空间: 答:int *p; p=new int; *p=100; delete p; 注意如果要对这一内存地址进行操作,需要使用*号。 27. 什么是虚函数和纯虚函数: 答:虚函数用来建立抽象模型,从而达到方便系统扩展的目的,纯虚函数是指标明不具体实现的虚函数,是一种特别的虚函数。虚函数必须是基类定义的非静态函数,可以是protected活着public的。在一个类中,虚函数后面加上=0

C/C++ 复习

末鹿安然 提交于 2020-01-05 04:23:10
本文总结一下C++面试时常遇到的问题。C++面试中,主要涉及的考点有 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, new, delete等等 语法问题 类型转换 指针以及指针和引用的区别 面向对象的相关问题,如虚函数机制等 泛型编程的相关问题,如模板和函数的区别等 内存管理,如字节对齐(内存对齐)、动态内存管理、内存泄漏等 编译和链接 实现函数和类 本文不涉及STL的内容,有关STL的内容,会另有一篇文章专门总结。 零、序章 0.1 C++与C的对比 C++有三种编程方式:过程性,面向对象,泛型编程。 C++函数符号由 函数名+参数类型 组成,C只有函数名。所以,C没有函数重载的概念。 C++ 在 C的基础上增加了封装、继承、多态的概念 C++增加了泛型编程 C++增加了异常处理,C没有异常处理 C++增加了bool型 C++允许无名的函数形参(如果这个形参没有被用到的话) C允许main函数调用自己 C++支持默认参数,C不支持 C语言中,局部变量必须在函数开头定义,不允许类似for(int a = 0; ;;)这种定义方法。 C++增加了引用 C允许变长数组,C++不允许 C中函数原型可选,C++中在调用之前必须声明函数原型 C++增加了STL标准模板库来支持数据结构和算法 一

指针基本概念分析

﹥>﹥吖頭↗ 提交于 2020-01-04 09:07:15
文章目录 1 指针 1.1 *号的意义 1.2 传值调用与传址调用 1 指针 1.1 *号的意义 *号: 在指针声明时,*号表示所声明的变量为指针。 在指针使用时,*号表示取指针所指向的内存空间中的值。 小贴士: 对于指针我们需要知道: 指针是C语言中一种特别的变量。 指针所保存的值是内存的地址。 可以通过修改指针修改内存中的任意地址内容。 1.2 传值调用与传址调用 传值调用与传址调用: 指针是变量,因此可以声明指针参数。 当一个函数体内部需要改变实参的值,则需要使用指针参数。 函数调用时实参值将复制到形参。 指针适用于复杂数据类型作为参数的函数中。 # include <stdio.h> int swap ( int * a , int * b ) { int c = * a ; * a = * b ; * b = c ; } int main ( ) { int aa = 1 ; int bb = 2 ; printf ( "aa = %d, bb = %d\n" , aa , bb ) ; swap ( & aa , & bb ) ; printf ( "aa = %d, bb = %d\n" , aa , bb ) ; return 0 ; } 参考资料: C语言进阶剖析教程 来源: CSDN 作者: SlowIsFastLemon 链接: https://blog

动态内存分配与指向它的指针变量

谁说我不能喝 提交于 2020-01-04 05:49:44
1.动态内存分配的含义   c语言允许建立动态内存分配区域,以存放一些临时用的数据,这些数据不必再程序的声明部分定义,也不必等到函数结束时才释放,而是要随时开辟,不需要随时释放,这些数据是临时存放在一个特定的自由存储区(堆),可以根据需要向系统申请所需要大小的空间,由于未在声明部分定义它们为变量或数组,因此不能通过变量名或数组名去引用这些数据,只能通过指针来引用。 2.建立内存的动态分配   对内存的动态分配是通过系统提供的函数库来实现的,主要有malloc,calloc,free,realloc这四个函数: (1).使用malloc函数   其函数原型为void *malloc(unsigned int size);   其作用是在内存的动态存储区域中分配一个长度为size的连续空间,形参size的类型定义为无符号整形(不允许为负数)。次函数的值(即返回值)是所分配区域的第一个字节的地址,或者说,次函数是一个指针型函数,返回的指针指向该分配区域的开头位置,如:   malloc(100)//开辟100字节的临时分配区域,函数值为其第一个字节的地址   注意其指针的基类型为void,即不能执行任何类型的数据,只能提供一个地址,如果此函数未能成功执行(如内存空间不足),则返回空指针。 (2).使用calloc函数   其函数原型为void *calloc(unsigned n,

C语言指针与数组

亡梦爱人 提交于 2020-01-04 05:49:02
C语言指针与数组 数组的下标应该从0还是1开始? 我提议的妥协方案是0.5,可惜他们未予认真考虑便一口回绝 -- Stan Kelly-Bootle 1. 数组并非指针 为什么很多人会认为指针和数组始终应该可以互换的呢? 因为对数组的引用总是可以写成对指针的引用,而且确实存在一种指针和数组的定义完全相同的上下文环境, 不幸的是,这只是数组的一种极为普通的用法,并非所用情况下都是如此。 2. 什么是声明,什么是定义 C语言中对象必须有且只有一个定义,但它可以有多个extern声明. 定义:只能出现在一个地方, 确定对象的类型并分配内存 ,用于创建新的对象,例如 int a[100] 声明:可以多次出现,描述对象的类型,用于指代其他地方定义的对象(例如在其他文件里) 例如 extern int a[100] extern对象声明告诉编译器对象的类型和名字,对象的内存分配则在别处进行 3. 数组与指针的区别 出现在赋值左边的符号被称为 左值, 出现在赋值右边的符号被称为 右值。 编译器为每个变量分配一个地址(左值),这个地址在编译时可知,并且该变量在运行时一直保存于这个地址中。 存储于变量中的值(右值)只有在运行时才可知,如果需要用到变量中存储的值,编译器就发出指令从指定地址读入变量并将它存于寄存器中。 例如: char a[9] = "abcdefgh"; c = a[i]