c语言指针

C语言指针用法详解(二) 指针的算术运算

…衆ロ難τιáo~ 提交于 2020-03-01 12:24:00
例题1: Question : char a[20]; int *ptr = (int * )a; ptr++ Practice : Reason : #include <bits/stdc++.h> using namespace std; int main() { char a[20]; int *ptr = (int * )a;/// 强制类型转换不会改变a的类型 /*** ** 吾日三醒指针:指针的类型,指针指向的类型,指针指向哪里 ** ptr 的类型是 int* , 指向的类型是 int , 指向整形变量 a ***/ cout<<" befor : " << ptr<<endl; ptr++; cout<< " sizeof (ptr) "<< sizeof(ptr)<<endl; /*** ** ptr 类型是指针,指针的自增,当然是增加自身的大小了 ** sizeof(ptr) 为4, ptr 增加4 ***/ cout<<" after : "<<ptr<<endl; } 例题2: Question : int arr[20] = {0}; int *ptr = arr; for (int i=0; i<20; i++) { (*ptr)++; ptr++; } Practice : Reason : #include <bits/stdc++.h> using

指针加减法运算的“定义域”

吃可爱长大的小学妹 提交于 2020-03-01 12:21:59
  指针变量加(减)一个整数。   例如:p++,p--,p+i,p-i,p+=i,p-=i等均是指针变量加(减)一个整数。   将该指针变量的原值(是一个地址)和它指向的变量所占用的存储单元的字节数相加(减)。     ————谭浩强 ,《C程序设计》(第四版),清华大学出版社,2010年6月,p290    在C语言中,任何运算都有前提条件。脱离了前提谈运算是荒谬的。   比如,一元“*”运算,其运算对象必须是非void *类型的指针。如果对一个int类型的数据或unsigned类型的数据做一元“*”运算,连编译都无法通过(这也间接说明了指针并非是一个32位无符号整数。参见§246)。   再比如,两个int类型数据相加,其前提条件是结果必须在int类型可以表示的范围之内,否则就成了一种未定义行为(undefined behavior)。   指针运算也是如此。并非所有的指针类型数据都有加(减)法运算。C语言并没有定义void *类型指针或指向函数的指针的加减法运算。换言之,指针的加减法运算只对那些指向数据对象(Object)类型的指针才可能有意义。比如:int *类型的指针可以做加减法运算。   指向数据对象类型的指针的加减法运算并没有限制运算对象是左值(lvalue)或可修改的左值(modifiable lvalue),用一句通俗的话来说

反汇编学习

让人想犯罪 __ 提交于 2020-02-29 07:06:48
(转: http://www.kuqin.com/assemble/20071122/2492.html ) 汇编语言和CPU以及内存,端口等硬件知识是连在一起的. 这也是为什么汇编语言没有通用性的原因. 下面简单讲讲基本知识(针对INTEL x86及其兼容机)   ============================   x86汇编语言的指令,其操作对象是CPU上的寄存器,系统内存,或者立即数. 有些指令表面上没有操作数, 或者看上去缺少操作数, 其实该指令有内定的操作对象, 比如push指令, 一定是对SS:ESP指定的内存操作, 而cdq的操作对象一定是eax / edx.    在汇编语言中,寄存器用名字来访问. CPU 寄存器有好几类, 分别有不同的用处:   1. 通用寄存器:   EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP(这个虽然通用,但很少被用做除了堆栈指针外的用途)      这些32位可以被用作多种用途,但每一个都有"专长". EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器. EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址. ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器. EDX是...(忘了..哈哈)但它总是被用来放整数除法产生的余数.

C语言指针的长度和类型

爱⌒轻易说出口 提交于 2020-02-29 06:27:00
本文地址: http://www.cnblogs.com/archimedes/p/point-length-type.html ,转载请注明源地址。 如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样。但是函数指针长度可能与数据指针的长度不同。 指针的长度取决于使用的机器和编译器,例如:在现代windows上,指针是32位或是64位长 测试代码: #include<stdio.h> #include<math.h> #include<stdlib.h> #include<stddef.h> struct p{ int n; float f; }; int main() { struct p *sptr; printf("sizeof *char: %d\n", sizeof(char*)); printf("sizeof *int: %d\n", sizeof(int*)); printf("sizeof *float: %d\n", sizeof(float*)); printf("sizeof *double: %d\n", sizeof(double*)); printf("sizeof *struct: %d\n", sizeof

指针与引用的区别

此生再无相见时 提交于 2020-02-28 22:16:39
标题 :指针与引用的区别 首先,函数参数有三种。一是传值,二是传地址,三是传引用。 传值,简单的来说,就是复制这个值,然后将复制体传到子函数中,对于其任何改变,其本身并不会变化。 传地址,就是将该变量的门牌号传给子函数,在子函数中对于其改变,本身也变化。 传引用,粗暴地说就是取小名。两个变量名指的是同一变量。改变时相互的。 是指针是C语言的精华,引用是C++对C语言的扩充。 首先来看指针。 # include <stdio.h> void swap ( int * a , int * b ) ; int main ( ) { int a = 3 , b = 4 ; swap ( & a , & b ) ; printf ( " a = %d ,b = %d" , a , b ) ; return 0 ; } void swap ( int * a , int * b ) { int temp ; temp = * a ; * a = * b ; * b = temp ; } 再来看引用 # include <iostream> using namespace std ; void swap ( int & a , int & b ) ; int main ( ) { int m = 3 , n = 4 ; swap ( m , n ) ; cout << "m=" << m <<

第十次实验总结

╄→гoц情女王★ 提交于 2020-02-27 20:47:30
知识点总结: 1.这周新开的章节是指针。 对于指针变量 ·一般形式:类型名 *指针变量名; ·定义指针变量要使用指针声明符*; 例如:int i,*p; (声明变量i是int类型,变量p是指向int型变量的指针。指针值可以是特殊的地址0,也可以是一个代表机器地址的正整数。) ·定义多个指针变量时,每一个指针变量前面都必须加上*; 注:指针变量的类型不是指指针变量本事的类型,而是指它所指向的变量的数据类型。无论何种类型的指针变量,它们都是用来存放地址的,因此指针变量自身所占的内存空间大小和它所指向的变量数据类型无关,尽管不同类型的变量所占的内存空间不同,但不同类型指针变量所占的内存空间大小都是相同的。 ·指针变量被定义后,必须将指针变量和一个特定的变量进行关联后才可以使用它,也就是说,指针变量也要先赋值再使用,当然指针变量被赋的值应该是地址。 ·定义指针变量:指针变量名是一个标识符,要按照c标识符的命名规则对指针变量进行命名。指针变量的数据类型是它所指向的变量的类型,一般情况下一旦指针变量的类型被确定后,它只能指向同种类型的变量。在定义指针变量是需要使用指针声明符*,但指针声明符并不是指针的组成部分。例如:定义 int *p;说明p是指针变量,而不是*p。 2.指针的基本运算 ·取地址运算和间接访问运算:单目运算符&用于给出变量的地址。(指针的类型和它所指向变量的类型必须相同)

简单讲述我对指针和结构体的一些理解

时光总嘲笑我的痴心妄想 提交于 2020-02-27 03:05:49
大家可以写几行代码好好想想这些东西。编译出来看就很好理解了。 指针概述 指针在C语言可以理解为一个对象,利用地址,她的值直接向存在电脑内存储存器中的另一个地方的值。可以说,地址指向该单元变量,所以将地址形象化的称为“指针”。我们可以理解为指针是个变量,存放内存单元的地址。指针是一个存放地址的变量。 指针的大小在32位平台是四个字节,在64位平台是八个字节。 指针类型 指针一般存放什么类型的变量,指针就定义为什么类型。 eg: int* char* flaot* /等等都可以定义指针变量 指针类型的意义就在于当指针±整数时,决定指针向前或者向后走一步的距离有多大(地址的变化) 指针类型也同样决定了,对指针解引用的时候有多大的权限(可以操作几个字符).char* /的指针解引用只可以访问一个字节,而int* /的指针的解引用就可以访问四个字节。 野指针 野指针可以理解为错误的使用指针。使指针指向的位置是不可知的。 规避野指针出现的方法:指针初始化;小心指针越界;指针指向空间释放即使置NULL;指针使用之前检查其有效性。 指针与数组 int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int* p = arr; 数组名表示的是数组首元素的地址。 可以直接通过指针来访问数组。 二级指针 int a = 10; int *pa = &a; int **ppa =

C语言实现反转链表 II(指定2个节点反转)

人走茶凉 提交于 2020-02-27 00:50:34
要求: 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 方法迭代链接反转 算法 在看具体算法之前,有必要先弄清楚链接反转的原理以及需要哪些指针。举例而言,有一个三个不同结点组成的链表 A → B → C,需要反转结点中的链接成为 A ← B ← C。 假设我们有两个指针,一个指向结点 A,一个指向结点 B。 分别记为 prev 和 cur。则可以用这两个指针简单地实现 A 和 B 之间的链接反转: cur.next = prev 这样做唯一的问题是,没有办法继续下去,换而言之,这样做之后就无法再访问到结点 C。因此,我们需要引入第三个指针,用于帮助反转过程的进行。因此,我们不采用上面的反转方法,而是: third = cur.next cur.next = prev prev = cur cur = third 迭代 地进行上述过程,即可完成问题的要求。下面来看看算法的步骤。 1.如上所述,我们需要两个指针 prev 和 cur。 2.prev 指针初始化为 None,cur 指针初始化为链表的 head。 3.一步步地向前推进 cur 指针,prev 指针跟随其后。 4.如此推进两个指针,直到

C++笔记(3):一些C++的基础知识点

99封情书 提交于 2020-02-26 23:05:08
前言: 找工作需要,最近看了下一些C++的基本概念,为范磊的 《零起点学通C++》,以下是一些笔记。 内容:   delete p;只是删除指针p指向内存区,并不是删除指针p,所以p还是可以用的。删除空指针所指向内存是可以的。   堆中的变量和对象时匿名的,没有名称,只能通过指针来访问。   在堆中创建对象时,在分配内存的同时会调用类的构造函数,在删除堆中对象时,会调用类的析构函数。   为了避免内存泄露,在删除一个指针后应该将其其值赋为0。   常量指针是指针指向的内存区域地址不能改变,但是该内存地址里保存的值是可以改变的,比如int a; int * const p = &a;   指向常量的指针表示指针指向的对象是不能被修改的,但是该指针可以被修改,即该指针可以指向另一块目标内存地址。比如const int a = 0; const int *p = &a; 如果A是一个类,也可以为const A* p = new A;   而指向常量的常指针表示指针本身不能被修改,其指向的内存地址内容也不能被修改。比如const int a = 0; const int * const p = &a;   引用就是别名常量。   堆中的地址是用指针来操作的,用不到别名。   如果在main函数前面的其它函数的声明和定义是一起的,则表明这个函数是内联函数!因此当该函数较长时

C语言指针变量的定义和使用

时间秒杀一切 提交于 2020-02-26 16:33:46
指针变量的含义 数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量 。 在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。指针变量的值就是某份数据的地址,这样的一份数据可以是数组、字符串、函数,也可以是另外的一个普通变量或指针变量。 定义指针变量 定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为: datatype * name ; 或者 datatype * name = value ; *表示这是一个指针变量,datatype表示该指针变量所指向的数据的类型 。例如: int * p1 ; p1 是一个指向 int 类型数据的指针变量,至于 p1 究竟指向哪一份数据,应该由赋予它的值决定。再如: int a = 100 ; int * p_a = & a ; 在定义指针变量 p_a 的同时对它进行初始化,并将变量 a 的地址赋予它,此时 p_a 就指向了 a。值得注意的是,p_a 需要的一个地址,a 前面必须要加取地址符&,否则是不对的。 指针变量也可以被多次写入,只要你想,随时都能够改变指针变量的值,请看下面的代码: //定义普通变量 float a = 99.5 , b = 10.6 ; char c = '@' , d = '#' ; //定义指针变量 float * p1 = & a ; char *