c语言指针

【数据结构 100讲】2 单链表定义

匿名 (未验证) 提交于 2019-12-02 23:34:01
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zztingfeng/article/details/90342730 1、链表是动态分配存储空间的链式存储结构。 其包括一个“头指针”变量,其中第0个结点称为整个链表的头结点,头结点中存放一个地址,该地址指向一个元素,头结点一般不存放具体数据,只是存放第一个结点的地址。 链表中每一个元素称为“结点”,每个结点都由两部分组成:存放数据元素的数据域和存储直接后继存储位置的指针域。指针域中存储的即是链表的下一个结点存储位置,是一个指针。多个结点链接成一个链表。 最后一个结点的指针域设置为空(NULL),作为链表的结束标志,表示它没有后继结点。 使用结构体变量作为链表中的结点,因为结构体变量成员可以是数值类型,字符类型,数组类型,也可以是指针类型,这样就可以使用指针类型成员来存放下一个结点的地址,使其它类型成员存放数据信息。 当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。 2、单链表的示意图 Head指针为单链表的头指针,单链表L:L既是单链表的名字,也是其头指针。链表中的最后一个结点的指针域定义为空指针(NULL)。 3、链表的分配函数 在创建列表时要动态为链表分配空间,C语言的库函数提供了几种函数实现动态开辟存储单元。 malloc()函数实现动态开辟存储单元:

C语言中void*详解及应用

匿名 (未验证) 提交于 2019-12-02 23:32:01
void在英文中作为名词的解释为“空虚;空间;空隙”;而在C语言中,void被翻译为“无类型”,相应的void *为“无类型指针”。void似乎只有“注释”和限制程序的作用,当然,这里的“注释”不是为我们人提供注释,而是为编译器提供一种所谓的注释。 本文地址: http://www.cnblogs.com/archimedes/p/c-void-point.html,转载请注明源地址。 void的作用: 1.对函数返回的限定,这种情况我们比较常见。 2.对函数参数的限定,这种情况也是比较常见的。 一般我们常见的就是这两种情况: 当函数不需要返回值值时,必须使用void限定,这就是我们所说的第一种情况。例如:void func(int a,char *b)。 当函数不允许接受参数时,必须使用void限定,这就是我们所说的第二种情况。例如:int func(void)。 void指针的使用规则: 1.void指针可以指向任意类型的数据,就是说可以用任意类型的指针对void指针对void指针赋值。例如: int *a; void *p; p=a; 如果要将void指针p赋给其他类型的指针,则需要强制类型转换,就本例而言:a=(int *)p。在内存的分配中我们可以见到void指针使用:内存分配函数malloc函数返回的指针就是void *型,用户在使用这个指针的时候,要进行强制类型转换

指针和字符串之间的联系

走远了吗. 提交于 2019-12-02 19:39:15
0.常见误区 c语言中没有string基本数据类型 C语言里有 <string.h> 这个头文件,所以就想当然的认为C语言里有string这个类型,通过下面这种形式来声明string的变量 string aString; 编译失败 。原来C语言里压根就 没有string 这个类型,所以字符串 都是通过char数组 来存储的, 而 <string.h> 这个头文件里声明的函数原型也全是 针对char数组的种种操作 。直到C++中才出现了string这个类(注意是类, 不是类型)。 字符串通过字符数组来定义时,默认会在数组最后一个元素加上'\0'作为结束标志 鉴于第二点,如果要区分普通的字符数组和字符串,参考如下代码 //此string1后面不会有'\0'标志,就是一般的字符数组 char string1[3]={'a','b','c'}; //string2为字符串形式,结尾有\0标志,长度为4 char string2[4]="abc" 注意:这里的string2的长度可以不限定,默认省略,交给编译器自动设定长度,如果需要人为设定长度,则需要考虑到'\0'字符 如果字符数组长度不够,则编译器报错 D:\otherworkspace\devcppworkspace\ds\ds-c2\demo5.cpp [Error] initializer-string for array of

C++第三章课后作业答案及解析---指针的使用

只愿长相守 提交于 2019-12-02 16:21:31
今天继续完成上周没有完成的习题---C++第三章课后作业,本章题涉及指针的使用,有指向对象的指针做函数参数,对象的引用以及友元类的使用方法等 它们具体的使用方法在下面的题目中会有具体的解析(解析标注在代码中)。 题目: 1.建立一个对象数组,内放5个学生数据(学号,成绩),设立一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生中成绩最高者,并输出其学号。 1 #include <iostream> 2 #include<stdlib.h> 3 using namespace std; 4 class Student 5 {public: 6 //定义学生数据函数 7 Student(int n,float s):num(n),score(s){} 8 int num; 9 float score; 10 }; 11 12 void main() 13 { 14 //构建五个学生数据信息 15 Student stud[5]={ 16 Student(101,78.5),Student(102,85.5),Student(103,98.5), 17 Student(104,100.0),Student(105,95.5)}; 18 void max(Student* );//定义max函数 19 Student *p=&stud[0];//p指向数组第一个元素

C语言指针使用malloc的问题

故事扮演 提交于 2019-12-02 14:53:49
最近在回顾C语言知识点时发现自己对指针的使用有些生疏了,把遇到的问题记录下来,以加深对指针的理解。 首先看下面的示例,实现将字符串反转输出,如“abcdef”, 输出为“fedcba”, 实现起来是不是很简单? 一开始我也这样觉得,下面是我第一次实现的代码: int main(void) { char *src = "Hello, World"; char *dest = NULL; int len = 0; len = strlen(src); dest = (char *)malloc(len+1); if (dest == NULL) { printf("dest malloc failed.\n"); return 0; } while (len-- != 0) { *dest++ = src[len]; } *dest = 0; printf(“Sting dest: %s\n”, dest); free(dest); return 0; } 看起开没问题,使用gcc -o test test.c也顺利编译通过了,但执行./test时发现竟然报错了,错误如下: *** Error in `./test_bak': munmap_chunk(): invalid pointer: 0x00000000023f201c *** ======= Backtrace: =====

C语言数组和指针的关系

大城市里の小女人 提交于 2019-12-02 14:39:27
案例: int matrix[3][10]; matrix[1][5] matrix: 指向包含10个整型元素的数组的指针, 指代第一行, 第一行是子数组 matrix+1: 指向包含10个整型元素的数组的指针+1表示第二行, 第二行是子数组 *(matrix+1): 对matrix+1进行间接访问操作, 选择第二行的子数组 *(matrix+1)+5: 这个指针比*(matrix+1)子数组上移动5个 *(*(matrix+1)+5) 和*(matrix[1]+5)相同, 对*(matrix+1)+5进行简介访问操作 ----------------------------------------------------------------------------------------- 源码: 1 #include<stdio.h> 2 3 int main() 4 { 5 int a[4][4]= 6 { 7 1, 2, 3, 4, 8 5, 6, 7 ,8, 9 9, 10, 11, 12, 10 13, 14, 15, 16 11 }; 12 int (*ps)[4]=a; 13 14 15 printf("\nps==%x\n", ps); 16 printf("\nps+1==%x\n", ps+1); 17 printf("\nps+2==%x\n", ps

二维字符数组和指针的相应问题研究

人走茶凉 提交于 2019-12-02 14:31:50
二维字符数组和指针的相应问题研究 在尝试用C语言实现广度优先算法时,需要用到支持以二维字符数组为值的哈希表,于是我对自己前面实现的int型键值对的哈希表进行再加工,发现在定义二维字符数组和指针时遇到较大问题,特此记录 shadowfish 2019/10/24 将已知的二维字符数组传入以储存 尝试 一开始,我将待传入的二维字符数组定义为 char a[][30]={"ABCD","EFDG","12122"}; 此代码创建了char类型3行30列 (3个字符串,每个字符串30个字节) 的二维数组。 接着,我尝试用一个二级指针指向它 char **ap =a; 并读取它的第一行字符串 printf("%s",*ap); 编译,运行到 printf("%s",*ap); 时报错 Segmentation fault ,即 段错误 ,访问了 不可访问 的内存。 原因 *ap 的值类型为 char* (指向char的指针) ,而它实际存储的是 char 型二维数组 a 的第一行数据的值 (本质是int型数据) ,而不是指向 a 的第一行数据的首地址。这就导致程序将 int 型数据当作地址访问,自然访问了 不可访问 的内存。 补充 char* p; 字符指针 p 相当于一维字符数组 名 , printf("%s",p) 中 p 指向字符数组首地址,配合 "%s"

数据结构笔记1(c++)_指针

匆匆过客 提交于 2019-12-02 12:59:35
一、数据结构概述 1.定义:     我们如何把现实中大量而复杂的问题,以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作。这个相应的操作也叫算法。   数据结构 =个体 + 个体的关系   算法(狭义) = 对存储数据的操作   2.算法:解题的方法和步骤   2.1.衡量算法好坏的标准:       2.1.1.时间复杂度: 程序 大概 执行的次数,而非执行的时间       2.1.2.空间复杂度: 算法执行过程中大概所占用的最大内存       2.1.3.难易程度(编算法最重要的)       2.1.4.健壮性 3.数据结构的地位:数据结构是软件中最核心的课程    程序 = 数据的存储 + 数据的操作 + 可以被计算机执行的语言 二、预备知识   1.指针     1.1.指针的重要性:指针是c语言的灵魂     1.2.有关指针概念的定义:       指针就是地址 地址就是指针,指针和地址是一个概念       指针变量 是存放内存单元地址的变量, 所谓内存单元地址 即为内存单元编号,两者是一个概念       指针的本质 是一个操作受限的非负整数/从0开始的非负整数                    范围:0 -- FFFFFFFF【4G-1】     

C语言中的4种强制类型转换!

半世苍凉 提交于 2019-12-02 11:39:35
前言 在C语言中,我们需要做类型转换时,常常就是简单粗暴,在C++中也可以用C式强制类型转换,但是C++有它自己的一套类型转换方式。 C式的显示类型转换 先来说说C式的强制类型转换,它的用法非常简单,形如下面这样 Type b =111; Typea a = (Typea)b; 只需要用括号将你要转换的类型扩起来,放在要转换的变量前面即可。 举个例子: #include<stdio.h> intmain(void) { inta =0x01020304; char*b = (char*)&a; inti =0; for(;i <4;i++) { printf("%02x\n",b[i]); } return0; } 编译运行输出结果: 04 03 02 01 如果你好奇为什么会是这样的结果,请参考 《字节序的那些事》 。 C++ 四种强制类型转换。 当然,C++也是支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以察觉.所以C++提供了一组可以用在不同场合的强制转换的函数。 const_cast , static_cast , dynamic_cast , reinterpret_cast const_cast 常量指针被转化成非常量的指针,并且仍然指向原来的对象; 常量引用被转换成非常量的引用,并且仍然指向原来的对象; const_cast一般用于修改指针

C/C++:深入分析 指针与引用的优缺点

泪湿孤枕 提交于 2019-12-02 11:39:26
前言 指针和引用本来就是两个完全不同的东西,引用甚至不能被称为对象。所以两者是没有可比性的,也没有什么意义去说谁比谁好,它们负责的工作也是不同的。但我以比较的方式写这篇文章,目的是能更浅显看出他们的特点。 一.常量引用与常量指针 疑难点1 首先我们需要知道的第一个东西是:绑定一个非常量引用必须要类型匹配,否则会显示”非常量引用的初始化值必须为左值“。就算你进行强制类型转换。这比指针可安全多了,因为指针就算被定义成常量指针,经过类型转换,也能够对其指向值进行修改。详细请看这篇博客: const==常量? 所以:在不对内存进行操作时,引用更加安全。 疑难点2 常量引用的第二个特点:常量引用可以绑定:任何一个可以转换成其类型的值都可以绑定。这是什么原理? 如我们执行以下操作时: double a; const int &b = a; 实际上编译器会先创建一个const int tmp的临时变量,然后将b绑定到这个临时变量上。为什么可以这样做? 因为绑定一个常量引用本来就不想通过这个引用改变其值,所以将其绑定在一个临时变量上是完全可行的。 但是如果你绑定的是一个非常量引用,你肯定是想通过这个引用修改值的,但如果采取绑定一个临时变量的方法,你就修改不了你想修改的那个变量的值。所以这样做是没有意义的,所以非常量引用的绑定必须类型匹配。 对于是否绑定在一个临时变量上,我们可以做以下测试: