C语言指针知识点总结
- 格式:docx
- 大小:1.39 MB
- 文档页数:3
C语言指针的长度和类型详解C语言指针的长度和类型详解指针是C语言的精髓,以下是店铺搜索整理的关于C语言指针的长度和类型详解,对于初学者深入理解C语言程序设计有很好的参考价值,有需要的朋友可以参考一下!想了解更多相关信息请持续关注我们店铺!一般来说,如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管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 ", sizeof(char*));printf("sizeof *int: %d ", sizeof(int*));printf("sizeof *float: %d ", sizeof(float*));printf("sizeof *double: %d ", sizeof(double*));printf("sizeof *struct: %d ", sizeof(sptr));return 0;}运行结果如下图所示:指针相关的预定义类型:① size_t:用于安全地表示长度② ptrdiff_t:用于处理指针算术运算③ intptr_t:用于存储指针地址④ uintptr_t:用于存储指针地址分述如下:一、size_t类型size_t 类型是标准C库中定义的,应为unsigned int,在64位系统中为long unsigned int。
c语言指针的优先级
C语言中,指针是一个非常重要的概念,它可以用来存储内存地址并访问内存中的数据。
在使用指针时,需要注意指针的优先级,因为它会影响到程序的执行结果。
C语言中,指针的优先级从高到低依次为:括号、*、&、+、-、++、--。
其中,括号的优先级最高,可以改变表达式的计算顺序;* 和& 的优先级相同,但是它们的结合方向是从右到左;+ 和 - 的优先级相同,但是它们的结合方向是从左到右;++ 和 -- 的优先级最低,它们的结合方向也是从右到左。
在实际编程中,需要根据具体情况灵活运用指针的优先级。
例如,在使用指针作为函数参数时,如果要传递指针所指向的值,需要使用* 运算符;如果要传递指针本身的地址,需要使用 & 运算符。
在对指针进行运算时,需要注意运算符的优先级,避免出现不必要的错误。
总之,掌握指针的优先级是 C 语言程序员必备的技能之一,对于编写高效、正确的程序非常重要。
- 1 -。
指针★指针的重要性表示一些复杂的数据结构快速传递数据使函数返回一个以上的值能直接访问硬件能方便处理字符串是理解面向对象语言中引用的基础总结:指针是C 语言的灵魂★指针的定义 ☆地址内存单元的编号 从零开始的非负整数 范围:4G ☆指针1.指针就是地址,地址就是指针2.指针变量是存放地址的变量3.指针和指针变量是两个不同的概念4.叙述时通常把指针变量简称为指针,实际它们含义不一样5.指针的本质就是一个操作受限的非负整数 ★指针的分类☆基本类型指针(重要) #include<stdio.h> int main(void)Int f(int i,int j){return 100;// return 88;error }Int main (void){Int a=3,b=5;# include <stdio.h> Void g(int*p,int*q){*p=1;*q=2; } Int main(void) {Int a=3,b=5;{int *p; //p是变量的名字,int*表示p变量存放的是int类型变量的地址Int*p;不表示定义了一个名字叫做*p的变量Int*p;应该理解为:p是变量名,p变量的数据类型是int*类型所谓int*类型,实际就是存放int变量地址的类型int i=3;char ch=’A’p=&i; //OK1.p保存了i的地址,因此p指向i2.p不是i,i也不是p,修改p的值不影响i的值,修改i的值也不影响p的值3.如果一个指针变量指向了某个普通变量,则*指针变量完全等同于普通变量例:若p指向i,则*p=i (*p和i 可互相替换)p=&ch;//error//p=i; //error,因为类型不一致,p只能存放int类型变量的地址,不能存放int类型变量//P=55;//error,原因同上return 0;}△附注:?*的含义:1.乘法2.定义指针变量Int*p; //定义了一个名字叫做p的变量,int*表示p只能存放int变量的地址3.指针运算符该运算符放在已经定义好的指针变量的前面如果p是一个已经定义好的指针变量则*p 表示以p 的内容为地址的变量 ?如何通过被调函数修改主调函数普通变量的值 1.实参必须为该普通变量的地址 &... 2.形参必须为指针变量 *...3.在被调函数中通过 *形参名=...... 的方式就可以修改主调函数相关变量的值 例子: 经典指针程序:互换数值形参和实参是不同的变量,修改形参不会改变实参 ?指针常见错误 #include<stdio.h> Int main(void) { Int i=5; Int*p; Int*q; P=&i;//*q=p;//error 语法编译会出错 //*q=*p;//errorP=q;//q 是垃圾值,q 赋给p ,p 也是垃圾值 printf(“%d\n ”,*q); //13行/*q 的空间是属于本程序的,所以本程序可以读写q 的内容,但是如果q 内部是垃圾值,则本程序不能读写*q 的内容因为此时*q 所代表的内存单元的控制限权并没有分配给本程序 所以本程序运行到13行时就会立即出错*/ return 0;#include<stdio.h>void huhuan (int a, int b ) { int t; t=a; a=b; b=t; return; }int main(void) { int a=3; int b=5;huhuan(a,b);#include<stdio.h> void huhuan2(int *p, int *q ) {int *t;//如果要互换p 和q 的值, 则t 必须是int*,不能是int t=p; p=q; q=t; return;}int main(void){int a=3;int b=5; #include<stdio.h>void huhuan3(int *p, int*q ) //形参的名字是p 和q ,接收实参数据的是p 和q ,而不是*p 和*q{int t;//如果要互换*p 和*q 的值, 则t 必须是int ,不能是int* t=*p;//p 是int*,*p 是int *p=*q; *q=t; return; }int main(void) {int a=3;int b=5;}☆指针和数组△指针和一维数组 ?一维数组名一维数组名是个指针常量它存放的是一维数组第一个元素的地址 ?下标和指针的关系如果p 是个指针变量,则p[i]永远等价于*(p+i) ?确定一个一维数组需要几个参数(如果一个函数要处理一个一维数组,则需要接收该数组的哪些信息) 需要两个参数:数组第一个元素的地址 数组的长度?指针变量的运算 指针变量不能相加,不能相乘,不能相除 可以相减(仅当两个指针变量指向的是同一块连续空间中的不同存储空间) ?一个指针变量到底占几个字节 预备知识: sizeof (数据类型)功能:返回值就是该数据类型所占的字节数例子:sizeof (int )=4 sizeof (char )=1 sizeof (double )=8 # include<stdio.h>//f 函数可以输出任何一个一维数组的内容 void f(int * pArr, int len) { int i ; for(i=0,i<len,++i) printf( “%d ”,*(pArr+i) ) //*(pArr+i)等价于pArr[i] b[i] *(b+i) int main(void){ int a[5]={1,2,3,4,5}; int b[6]={-1,-2,-3,4,5,-6};int c[100]={1,99,22,33}; f(a,5);//a 是int*f(b,6); 1 2 3 4 5 -1 -2 -3 4 5 -61 99 22 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # include<stdio.h>void f(int * pArr,int len) { pArr[3]=88; //10行} int main(void) { int a[6]={1,2,3,4,5,6} printf(“%d\n ”,a[3]); //17行 f(a,6); printf(“%d\n ”,a[3]); //19行 若写为&a[3]则输出结果为a[3]的地址 #include<stdio.h> Int main(void){ int i=5;Int j=10; Int*p=&i; #include<stdio.h> Int main(void) { int i=5; Int j=10; Int*p=&i; Int*q=&j; Int a[5]; p=&a[1];#include<stdio.h>Void f(int*pArr,int len){ pArr[2]=10; //pArr[2]==*( pArr+2)==*(a+2)==a[2]}Int main(void) { int a[6]={1,2,3,4,5,6} printf(“%d\n ”,a[2]);f(a,5);printf(“%d\n ”,a[2]); //a=&a[2];//error 因为a 是常量# include<stdio.h> Void OutArr(int*pArr,int len) {Int i; For(i=0;i<len;++i)Printf(“%d\n ”,pArr[i]);}Int main(void) { OutArr(a,5);Return 0; }sizeof (变量名)功能:返回值是该变量所占的字节数 假设p 指向char 类型变量(1个字节) 假设q 指向int 类型变量(4个字节) 假设 r 指向double 类型变量(8个字节)△指针和二维数组☆指针和函数 ☆指针和结构体 ☆多级指针 专题:动态内存分配(重难点)传统数组的缺点:1.数组长度必须事先制定,且只能是常整数,不能是变量。
总结课:让你不再害怕指针指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存。
0前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧:int p;//这是一个普通的整型变量int*p;//首先从P处开始,先与*结合,所以说明P是一//个指针,然后再与int结合,说明指针所指向//的内容的类型为int型.所以P是一个返回整//型数据的指针int p[3];//首先从P处开始,先与[]结合,说明P是一个数//组,然后与int结合,说明数组里的元素是整//型的,所以P是一个由整型数据组成的数组int*p[3];//首先从P处开始,先与[]结合,因为其优先级//比*高,所以P是一个数组,然后再与*结合,说明//数组里的元素是指针类型,然后再与int结合,//说明指针所指向的内容的类型是整型的,所以//P是一个由返回整型数据的指针所组成的数组int(*p)[3];//首先从P处开始,先与*结合,说明P是一个指针//然后再与[]结合(与"()"这步可以忽略,只是为//了改变优先级),说明指针所指向的内容是一个//数组,然后再与int 结合,说明数组里的元素是//整型的.所以P 是一个指向由整型数据组成的数//组的指针int**p;//首先从P开始,先与*结合,说是P是一个指针,然//后再与*结合,说明指针所指向的元素是指针,然//后再与int 结合,说明该指针所指向的元素是整//型数据.由于二级指针以及更高级的指针极少用//在复杂的类型中,所以后面更复杂的类型我们就//不考虑多级指针了,最多只考虑一级指针.int p(int);//从P处起,先与()结合,说明P是一个函数,然后进入//()里分析,说明该函数有一个整型变量的参数//然后再与外面的int结合,说明函数的返回值是//一个整型数据int(*p)(int);//从P处开始,先与指针结合,说明P是一个指针,然后与//()结合,说明指针指向的是一个函数,然后再与()里的//int结合,说明函数有一个int型的参数,再与最外层的//int结合,说明函数的返回类型是整型,所以P是一个指//向有一个整型参数且返回类型为整型的函数的指针int*(*p(int))[3];//可以先跳过,不看这个类型,过于复杂//从P开始,先与()结合,说明P是一个函数,然后进//入()里面,与int结合,说明函数有一个整型变量//参数,然后再与外面的*结合,说明函数返回的是//一个指针,,然后到最外面一层,先与[]结合,说明//返回的指针指向的是一个数组,然后再与*结合,说//明数组里的元素是指针,然后再与int结合,说明指//针指向的内容是整型数据.所以P是一个参数为一个//整数据且返回一个指向由整型指针变量组成的数组//的指针变量的函数.说到这里也就差不多了,我们的任务也就这么多,理解了这几个类型,其它的类型对我们来说也是小菜了,不过我们一般不会用太复杂的类型,那样会大大减小程序的可读性,请慎用,这上面的几种类型已经足够我们用了.1、细说指针指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
c语言指针教学中的知识点分析与总结c语言指针教学中的知识点分析与总结本文对c语言指针的教学进行了探讨和总结。
要想真正的掌握c 语言的指针,首先必须要对它有全面深刻的认识。
因为它是c语言的基础,只有将指针的知识学好,才能够更好地学习后续的课程。
下面小编给大家介绍一下关于c语言指针的知识。
一、 c语言中指针的定义指针是一种特殊的数据类型,也称为引用类型。
所谓指针就是指向一个地址的变量,例如: int a[10];二、变量指针及指针变量1.1 c语言中的变量。
变量是存储在计算机中的二进制数值,当我们需要使用时,必须创建一个变量并赋予它相应的值,然后将变量的地址传递给外部的一个或多个对象,这样外部对象通过访问内部变量来使用其中存储的信息,而且可以保证外部对象不会越界。
1.2指针变量是变量的一种特殊形式,指针变量在内存中占有一块区域,可以指向一个地址,这个地址的值是这个变量所代表的值,这样方便变量间的传递。
例如: char *a[10];2.1指针操作符2.2指针数组,它的作用和一维数组相同,即具有一维数组的特点,也具有二维数组的特点,三者最明显的区别就是二维数组中元素个数是固定的,而一维数组中元素个数是可变的。
2.3指针的运算规则。
在指针变量的操作中,要遵循以下运算规则:原地址→指针地址。
例如: char * a[10]; 2.4 c语言中的const指针常量是一种特殊的指针常量, const不是一种变量的标准类型,它专门用于指向一个const指针。
2.3指针的运算规则。
在指针变量的操作中,要遵循以下运算规则:原地址→指针地址。
例如: char *a[10];2.4指针的定义与使用:所谓指针就是指向一个地址的变量,例如: int a[10]; 2.4指针的定义与使用: pointer, pointer-pointer,and-and-and。
所以,当我们在一个字符串中出现pointer,pointer-pointer, and-and-and的时候,就表示它指向一个地址。
c语言中的指针详解在C语言中,指针是一种特殊的变量类型,它存储了一个变量的内存地址。
通过指针,我们可以间接访问和修改内存中的数据,这对于一些需要动态分配内存的操作非常有用。
以下是关于C语言指针的一些详细解释:1. 定义指针:使用"*"符号来定义指针变量。
例如,int* ptr; 定义了一个指向整型变量的指针 ptr。
2. 取址操作符(&):取地址操作符(&)用于获取变量的内存地址。
例如,&a 返回变量 a 的地址。
3. 解引用操作符(*):解引用操作符(*)用于访问指针所指向的变量的值。
例如,*ptr 返回指针 ptr 所指向的整型变量的值。
4. 动态内存分配:可以使用相关的库函数(如malloc和calloc)在运行时动态分配内存。
分配的内存可以通过指针来访问和使用,并且在使用完后应该使用free函数将其释放。
5. 空指针:空指针是一个特殊的指针值,表示指针不指向任何有效的内存地址。
可以将指针初始化为NULL来表示空指针。
6. 指针和数组:指针和数组在C语言中有密切的关系。
可以通过指针来访问数组元素,并且可以使用指针进行指针算术运算来遍历数组。
7. 传递指针给函数:可以将指针作为函数参数传递,以便在函数内部修改实际参数的值。
这种传递方式可以避免拷贝大量的数据,提高程序的效率。
8. 指针和字符串:字符串在C语言中实际上是以字符数组的形式表示的。
可以使用指针来访问和操作字符串。
需要注意的是,指针在使用时需要小心,因为不正确的操作可能导致程序崩溃或产生不可预料的结果。
对于初学者来说,理解指针的概念和使用方法可能需要一些时间和练习。
c语言二级指针详解C语言中,指针是一种重要的数据类型,它可以指向另一个变量或者数据结构中的一个元素,并且可以进行不同种类的操作(如解引用、赋值、比较、运算等)。
在C语言中,指针本身也是一个变量,它具有一个内存地址,并且其值就是指向的地址。
而指针变量可以通过指定自己的类型来控制指向的变量或者数据结构元素的类型。
在C语言中,指针本身也可以被指针所指向,这样的指针就被称为“二级指针”或者“指向指针的指针”。
二级指针在一些情况下比普通指针更加灵活,比如当我们需要在函数内部进行指针变量的修改或者返回值时,就可以使用二级指针。
1、指向指针的指针需要使用两个星号(**)来声明,例如:int **p;2、在函数中传递指向指针的指针时,需要将变量的地址传递给函数,而函数需要使用指向指针的指针来访问实际的指针变量。
3、在使用二级指针时,我们需要防止指针变量指向非法内存地址,否则会导致程序出现意想不到的错误。
二级指针是C语言中非常重要的概念,尤其在函数调用和指针变量的修改或返回值时,更是非常有用。
不过,我们在使用二级指针时需要额外注意指向内存地址的合法性,否则会导致程序出现异常。
二级指针是指指向指针对象的指针,即指针的指针,它可以通过间接的方式访问一个指针变量所指向的地址,这种间接的访问方式可以增加程序的灵活性,从而使程序更加易于理解和维护。
1、动态内存管理在C语言中,动态内存分配是通过调用malloc函数来实现的,而释放动态内存则需要使用free函数。
在使用malloc函数分配内存时,它会返回一个指针,指向分配的内存空间的首地址,我们可以将这个指针赋值给一个普通的指针变量,然后通过这个普通指针变量来访问分配的内存空间。
不过,当我们使用malloc来分配一个指针数组时,我们就需要使用二级指针来存储这个指针数组的首地址。
int **p = (int **)malloc(sizeof(int *) * 10);for (int i = 0; i < 10; ++i) {p[i] = (int *)malloc(sizeof(int) * 10);}以上代码中,我们使用了二级指针来存储指向指针数组的地址,然后使用循环语句来为每一个指针分配空间。
C语言指针知识点总结 Revised by BETTY on December 25,2020
指
针 ★指针的重要性
表示一些复杂的数据结构 快速传递数据
使函数返回一个以上的值 能直接访问硬件 能方便处理字符串
是理解面向对象语言中引用的基础 总结:指针是C 语言的灵魂 ★指针的定义 ☆地址
内存单元的编号 从零开始的非负整数 范围:4G ☆指针
1.指针就是地址,地址就是指针
2.指针变量是存放地址的变量
3.指针和指针变量是两个不同的概念
4.叙述时通常把指针变量简称为指针,实际它们含义不一样
5.指针的本质就是一个操作受限的非负整数 ★指针的分类
☆基本类型指针(重要) #include<> int main(void) {
int *p; 果一个指针变量指向了某个普通变量,则*指针变量 完全等同于 普通变量 例:若p 指向i ,则*p=i (*p 和i 可互相替换)
p=&ch;法
2.定义指针变量 Int*p; 针运算符
该运算符放在已经定义好的指针变量的前面 如果p 是一个已经定义好的指针变量 则*p 表示以p 的内容为地址的变量
如何通过被调函数修改主调函数普通变量的值 1.实参必须为该普通变量的地址 &... 2.形参必须为指针变量 *...
3.在被调函数中通过 *形参名=...... 的方式就可以修改主调函数相关变量的值 例子: 经典指针程序:互换数值
形参和实参是不同的变量,修改形参不会改变实参 指针常见错误 #include<> #include<>
void huhuan (int a, int b )
{ int t;
t=a; a=b; b=t;
#include<> void huhuan2(int *p, int *q ) { int *t;//如果要互换p 和q 的值,
则t 必须是int*,不能是int
t=p;
#include<> void huhuan3(int *p, int*q ) //形参的名字是p 和q ,接收实参数据的是p 和q ,而不是*p 和*q {
int t;//如果要互换*p 和*q 的值, Int f(int i,int j) {
return 100; // return 88;error
}
Int main (void) {
Int a=3,b=5; a=f(a,b);
b=f(a,b);
}
只能返回一个值 # include <> Void g(int*p,int*q) {
*p=1; *q=2; }
Int main(void) {
Int a=3,b=5; g(&a,&b); Printf(“%d%d\n ”,a,b); Return 0;
}
指针使函数返回一个以上的值
Int main(void) {
Int i=5; Int*p; Int*q; P=&i;
组长度必须事先制定,且只能是常整数,不能是变量。
例子:int a[5]; 统形式定义的数组,该数组的内存程序员无法手动释放 为什么需要动态分布内存 动态内存分配举例-动态数组的构造 静态内存和动态内存的比较 跨函数使用内存的问题 # include<> //f 函数可以输出任何一个一维数组的内容 void f(int * pArr, int len) { int i ; for(i=0,i<len,++i) printf( “%d ”,*(pArr+i) ) //*(pArr+i)等价于pArr[i] b[i] *(b+i) printf(“\n ”); } int main(void) { int a[5]={1,2,3,4,5}; int b[6]={-1,-2,-3,4,5,-6}; int c[100]={1,99,22,33}; f(a,5);//a 是int* f(b,6); f(c,100); return 0; } 1 2 3 4 5 -1 -2 -3 4 5 -6 1 99 22 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Press any key to # include<> void f(int * pArr,int len) { pArr[3]=88; //10行 } int main(void) { int a[6]={1,2,3,4,5,6} printf(“%d\n ”,a[3]); //17行 f(a,6); printf(“%d\n ”,a[3]); //19行 若写为&a[3]则输出结果为a[3]的地址 return 0; } /*在VC++中输出结果是 4 88*/
一定要明白10行的pArr[3]和 17行 19行的a[3]是同一个变量
#include<> Int main(void) { int i=5; Int j=10; Int*p=&i; Int*q=&j; //p-q 没有实际意义 Return 0; } #include<> Int main(void) { int i=5; Int j=10; Int*p=&i; Int*q=&j; Int a[5]; p=&a[1]; q=&a[4]; Printf(“p 和q 所指向的单元相隔%d 个单元\n ”,q-p); } p 和q 所指向的单元相隔3个单元 Press any key to continue #include<> Int main(void) { char ch=’A ’; Int i=99; Double x= Char * p=&ch; Int *q=&i; Double * r=&x; Printf(“%d%d%d\n ”,sizeof(p),sizeof(q),sizeof(r)) Return 0; } 4 4 4 Press any key to continue #include<> Void f(int*pArr,int len) { pArr[2]=10; //pArr[2]==*( pArr+2)==*(a+2)==a[2] } Int main(void) { int a[6]={1,2,3,4,5,6} printf(“%d\n ”,a[2]); f(a,5); printf(“%d\n ”,a[2]); //a=&a[2];//error 因为a 是常量 //printf(“%#X,%#X\n ”,a,&a[0]); //a==&a[0] Return 0; } 3 10
Press any key to continue
# include<> Void OutArr(int*pArr,int len) { Int i; For(i=0;i<len;++i) Printf(“%d\n ”,pArr[i]); } Int main(void) { OutArr(a,5); Return 0; } 1 2 3 4 5 Press any key to continue。