Ps:相信学过C语言的同学都知道,指针是C语言中最重要也是最难攻克的部分,下面的代码中的注释部分请同学们要仔细阅读

一、指针&指针变量

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>//32位编译器(0x0000 0000-0xffff ffff):
//指针变量:
//存放指针(地址)的变量
//因为地址编号(0x0000 0000)如此,所以我们指针变量占4个字节就可以存下
//64位编译器(0x0000 0000 0000 0000-0xffff ffff ffff ffff):
//指针变量占8个字节//指针变量的定义和初始化
//指针变量的定义:int main01()
{using namespace std;int a = 10;
定义指针的步骤:1.*与符号结合代表是一个指针变量2.要保存谁的地址,将他的定义形式放在此处3.用*p替换掉定义的变量定义指针变量的格式:数据类型   *    变量名!!注意!!指针变量的类型是  数据类型*(例:int *p的指针变量类型是int*,p是变量!!)int* p;分析与*结合代表这是一个指针变量p是变量,p的类型是将变量p本身拖黑,剩下的类型就是指针变量的类型指针变量p用来保存什么类型数据的地址,将指针变量p和指针变量p最近的*一起拖黑,//剩下什么类型就保存什么类型数据的地址p = &a;int* i_porint = &a;system("pause");return (0);}//指针的使用
//指针变量保存了谁的地址就指向了谁
int main02()
{//在使用(最常见是赋值时,因为等号两边数据类型要匹配)时,对一个表达式取*,就会对表达式减一级*,如果对表达式取&,就会加一级*using namespace std;int a = 10;int* p = &a;*p = 100;//在使用时,*与p结合代表,取p指针所指向的那块空间的内容cout << *p << endl;//*p:  p指向地址中的内容cout << p << endl;//p: p指向的地址空间cout << a << endl;//注意!!!&可以取得一个变量在内存中的地址,但是,不能取寄存器变量,因为寄存器变量不在内存里,而在CPU里面,所以是没有地址的system("pause");return (0);
}//指针变量的大小sizeof()
//不管什么类型的指针,大小只和系统或编译器的位数有关
int main03()
{using namespace std;char* p1;short* p2;int* p3;int** p4;cout << sizeof(p1) << endl;cout << sizeof(p2) << endl;cout << sizeof(p3) << endl;cout << sizeof(p4) << endl;system("pause");return (0);
}//指针的宽度和步长  宽度也可以理解成步长
int main04()
{using namespace std;int num = 0x01020304;char* p1 = (char*)&num;short* p2 = (short*)&num;int* p3 = &num;int** p4;printf("%x\n", *p1);//4printf("%x\n", *p2);//304printf("%x\n", *p3);//01020304//通过*取指针指针变量所指向的那块空间内容时,取的内存的宽度和指针变量本身的类型有关//指针的宽度(步长)=sizeof(将指针变量与指针变量最近的*拖黑,剩下的类型)//步长:指针+1跨过的字节数printf("%p\n", p1);printf("%p\n", p2);printf("%p\n", p3);printf("%p\n", p1 + 1);printf("%p\n", p2 + 1);printf("%p\n", p3 + 1);system("pause");return (0);
}//野指针
int main05()
{using namespace std;int* p;//*p=200;//printf("%d\n",*p)//野指针:就是没有初始化的指针,指针的指向时随机的不可以操作野指针//指针变量保存的地址一定是定义过的(向系统申请过)system("pause");return (0);
}//空指针
int main06()
{using namespace std;int a;//将指针的值赋值给0,0x00000000 = NULLint* p = NULL;//给指针p的内容赋值为0if (p != NULL){p = &a;}*p = 200;//错误    因为p保存了0x0000的地址,这个地址是不可以被赋值的printf("%d\n", *p);system("pause");return (0);
}//万能指针
int main07()
{using namespace std;//void b;  不可以定义void类型的变量,因为编译器不知道给变量分配多大的空间//但是可以定义void*类型,因为指针都是4个字节int a = 10;short b = 20;void* q = (void*)&b;void* p = (void*)&a;//万能指针可以保存任意的地址,在不知道所指向变量的数据类型时,//需要强制转换数据类型(为了保持赋值=两边数据类型匹配)printf("%d\n", *(int *)p);//*((int *)地址)system("pause");return (0);
}//const修饰的指针
int main08()
{using namespace std;const int a = 10;//修饰变量a,不能再通过a修改a内存里面的内容/* int *p;p = &a;*p = 100;*/system("pause");return (0);
}int main09()
{using namespace std;const int* p;//const在这里修饰的是*int a = 10;p = &a;//不能通过*p,改p所指向空间的内容//*p = 100;err  因为不能通过p改p所指向的内容//const修饰的指针变量p//p保存的地址不可以被修改,不能通过*p修改p所指向的那块空间的内容int* const p = &a;//p=&b;err  p本身的值不能被改变//不想被改变的数据,就用const修饰即可system("pause");return (0);
}

二、多级指针&数组与指针

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>//1.多级指针
int main10()
{using namespace std;int a = 10;int* p = &a;//现在需要定义一个指针去指向指针变量p所在的地址//p的数据类型是int*,  用新指针*q代替指针变量p,  数据类型是int*int** q = &p;//*q代表指针变量p中的内容--变量a的地址//**q代表的是a的值//**q==*(*q)==*(&a)==*(p)==a//如果*和&相遇则抵消int*** k = &q;//*与符号结合,代表这个k是一个指针变量//k是一个变量//k的类型,将变量k拖黑,整下的类型//k用来保存谁的地址,将变量k和k最近的*一起拖黑,剩下什么类型就保存什么类型数据的地址system("pause");return (0);
}//2.数组与指针
//通过指针操作数组元素
int main11()
{using namespace std;int a[10] = { 1,2,3,4,5,6,7,8,9,10 };int b[10] = { 0 };//a 数组名,首元素的地址int* p = a;//指针p保存的是首元素的地址for (int i = 0; i <sizeof(a)/sizeof(a[0]); i++){cout << a[i] << "   ";}cout << endl;for (int j=0; j < sizeof(a) / sizeof(a[0]); j++){cout << *(p + j) << "   ";}cout << endl;for (int z = 0; z < sizeof(a) / sizeof(a[0]); z++){*(p + z) = z;cout << *(p + z) << "   ";}cout << endl;system("pause");return (0);
}//指针的运算
int main()
{using namespace std;int a[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = a;//指针变量p指向数组a首元素地址int* q = (int*)(&a + 1) - 1;//&a的步长是整个数组,&a+1直接跨过数组a,//(int*):强制转化为指针类型,步长为四字节,(int*)(&a + 1) - 1 == int *q = &a[9];//或者:int *q = &a[9];cout << q - p << endl;//输出的是数组a的元素个数,cout << *(p + 3) << endl;//a[3]的值//在c语言中,两个指针相加,没有意义!!!!//两指针相减(类型一致),得到的是中间跨过多少元素system("pause");return (0);
}//[]不是数组的专属
int main13()
{using namespace std;int a = 10;int* p = &a;p[0] = 100;cout << "a=" << a << endl;//输出结果为a = 100//原因是,[]==*()//p[0] == *(p+0); int b[10] = { 1,2,3,4,5,6,7,8,9,10 };int* q = b;for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++){cout << b[i] << endl;cout << *(q + i) << endl;cout << q[i] << endl;//三者结果相同}system("pause");return (0);
}//3.指针数组
//整形数组:是一个数组,数组中的每一个元素都是整形
//指针数组:是一个数组,数组中的每一个元素都是指针
int main14()
{using namespace std;int a = 10;int b = 20;int c = 30;//int *p1 = &a   int *p2 = &b   int *p3 = &c;//需求: 数组中的每一个元素都是指针(地址)int* num[3] = { &a,&b,&c };//定义了一个指针数组,并且初始化//数组类型:int *  [3]cout << sizeof(num) << endl;//数组的长度cout << *num[0] << endl;//a的值for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++){cout << *num[i] << "   ";}cout << endl;int** p = num;cout << **p << endl;for (int j = 0; j < sizeof(num) / sizeof(num[0]); j++){cout << **(p + j) << "  ";}cout << endl;system("pause");return (0);
}

三、指针与函数

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>//1.指针与函数
//指针作为形参
int main15()
{using namespace std;void swap(int*, int*);int a = 10;int b = 20;int* p1 = &a;int* p2 = &b;swap(p1, p2);cout << "a=  " << a << endl;cout << "b=  " << b << endl;system("pause");return (0);
}
void swap(int* a, int* b)
{int temp;temp = (*a);(*a) = (*b);(*b) = temp;return;
}int main16()
{using namespace std;int a[10] = { 1,2,3,4,5,6,7,8,9,10 };return 0;
}

(续)

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>using namespace std;
int num = 0;//在函数外面定义的变量是全局变量,整个工程都可以使用
//这个变量程序启动开辟空间,知道程序结束时才释放空间
void print_arr(int b[10])//数组做形参,系统会自动转化为指针  int *b;
{for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++){cout << b[i] << "  ";}cout << endl;cout << sizeof(b) << endl;//打印结果为:4  说明数组做形参,就会退化为指针cout << sizeof(b[0]) << endl;//打印结果为:4  所以sizeof(b) / sizeof(b[0])==1,因此只会打印一个字节
}
void out_arr(int *b,int n)//n代表数组中的元素个数
{for (int i = 0; i < n; i++){cout << *(b+i) << "  ";}cout << endl;
}//1.数组名作为函数的参数
int main01()
{int a[10] = { 1,2,3,4,5,6,7,8,9,10 };print_arr(a);//打印数组内容//没有输出整个数组的值,只打印了第一个元素的值out_arr(a, sizeof(a) / sizeof(a[0]));system("pause");return 0;
}//2.指针作为函数的返回值
int* getnum()//函数的类型要与函数返回值的类型相同
{//函数{}中定义的变量是局部变量,局部变量在函数结束后的空间会被释放srand(time(NULL));num = rand();return &num;//返回值类型是指针(地址)类型
}int main02()
{int* p = getnum();cout << *p << endl;system("pause");return 0;
}

四、指针与字符数组

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>using namespace std;
//1.指针与字符数组
int main05()
{char a[] = "helloworld";//定义了一个字符数组,字符数组内容为helloworld\0//定义一个指针用来保存数组首元素的地址char* p = a;printf("%s\n", p);//打印一个字符串,要的是首个字符的地址printf("%s\n", p + 2);printf("%c\n", *(p+3));printf("%d\n", sizeof(a));//11printf("%d\n", sizeof(p));//4printf("%d\n", strlen(a));//10printf("%d\n", strlen(p));//10p++;printf("%s\n", p);//输出elloworld;//指针指向那个元素,打印时就从那个元素开始打印system("pause");return 0;
}int main06()
{char a[] = "helloworld";char* p = a;//p = "abcdef";//字符常量存文字常量区,p中存的是字符串首元素地址,“”在使用时,取的是字符串首元素的地址system("pause");return 0;
}//字符指针作为形参
char * my_strcat(char* scr, char* dst)
{int n = strlen(scr);int i = 0;while (i = strlen(dst)){scr[n + i] = dst[i];i++;}scr[i + 1] = 0;return scr;
}int main07()
{char str1[128] = "hello";char str2[128] = "123456";char* my_strcat(char*, char*);//将str2拷贝到str1后面//字符数组作为形参时,不用告知数组中元素的个数,因为字符数组中最后会有结束符'\0',判断什么时候出现结束符就可以了;cout << my_strcat(str1, str2) << endl;system("pause");return 0;
}//字符指针数组
//是一个数组,每一个元素时字符指针
int main08()
{int* arr[10];/*char* p1 = "heihei";char* p2 = "haha";char* p3 = "xixi";char* num[3] = { p1,p2,p3 };*///char* arr[3] = { "heihei","haha","xixi" };//把三个字符串常量的首地址存在数组里面for (int i = 0; i < 3; i++){cout << arr[i] << endl;//输出了三个字符串常量}cout << *arr[0] << endl;//输出结果为h;cout << *(arr[1] + 1) << endl;//输出结果为asystem("pause");return 0;
}//字符指针数组作为main函数参数
//.exe
//在没有给文件命令参数时,argc中保存的是1    argv中保存的是。exe文件的路径
//点击项目名称,右击选择属性-->调试-->命令参数处可以为main函数传参,各个参数的首地址存放在argv数组中
//char* argv[] = {".*.exe","hello","123456"};//argc是执行可执行程序的参数个数
//argv是一个字符指针数组,保存的是参数(字符串)的首元素地址
int main(int argc, char* argv[])
{cout << argc << endl;cout << argv[0] << endl;cout << argv[1] << endl;cout << argv[2] << endl;cout << argv[3] << endl;system("pause");return 0;
}

五、指针练习

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>using namespace std;
//1.找出数组中第二大的数,(使用*操作数组元素个数,不要使用[])
int main03()
{int a[] = { 100,100,100,234,123,500,32,68,41,99,13,71 };int* p = a;int* q = (int*)(&a + 1) - 1;int temp = 0;for (int i = 0; i < (q - p); i++){for (int j = 0; j < (q - p) - i ; j++){if (*(p + j) > *(p + j + 1)){temp = *(p + j);*(p + j) = *(p + j + 1);*(p + j + 1) = temp;}}}cout << *(q-1) << endl;cout << q-p << endl;system("pause");return 0;
}//不使用库函数,实现字符串拷贝功能
//char src[100] = "hello";
//char dst[100];  //把src的内容拷贝给dst
//函数名:void my_strcpy(char dst[],char src[]);int main04()
{char src[100] = "hello";char dst[100] = {0};char* p = src;char* q = dst;int i = 0;for (i = 0; *(p + i) != '\0'; i++){*(q + i) = *(p + i);//dst[i] = src[i];//q[i] = p[i];//*(dst+i) = *(src+i);//四者等价}*(q + i + 1) = '\0';//补结束符cout << "src= " << src << endl;cout << "dst= " << dst << endl;system("pause");return 0;
}

C语言学习(五)——指针相关推荐

  1. C语言 指针 规范,C语言学习知识指针习题集附规范标准答案.doc

    C语言学习知识指针习题集附规范标准答案.doc /*一.选择题1. 变量的指针,其含义是指该变量的_________. a值 b地址 c名 d一个标志2若有语句int *point,a4;和point ...

  2. c语言学习02指针总结

    本人工作Android开发越往高深方向专业,就越发现c语言的重要性.可以说java是简单的封装语言,但大量封装起来的不灵活,而Android的自带的java代码往往有些功能并不完美,这就导致高级开发就 ...

  3. c语言指针在左还是右,C语言学习之指针的右左法则

    C语言所有复杂的指针声明,都是由各种声明嵌套构成的.如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法.不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法.C标准的 ...

  4. C语言学习笔记---指针

    C语言要玩的好,指针是核心,但是指针在学习的时候看教程往往感觉一看就明白,但是实际用的时候一用就错,而且还不知道错在哪.为了更加深刻的了解指针,将学习过程记录下来,依次加深对指针的理解. 先看看一段测 ...

  5. c语言枚举如何当函数返回值,C语言学习五 — 数组与枚举

    数组 C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合.数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量. 数组的声明并不是声明一个个单独的变量,比如 numbe ...

  6. c语言中 程序各步作用,C语言学习网总结C语言学习五步曲

    很多人对C语言的第一感觉就是太难了,很难理解这种语言,也不知道该如何来理解,书也看了,视频也看了,但就是没什么太大的作用,那么C语言究竟该如何来学? C语言作为一门计算机语言,想要真正的掌握并使用需要 ...

  7. C语言学习笔记——指针章节

    学习小结 c语言指针学习笔记汇总 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//指针 //在计算机科学中,指针是编程语言的一个对 ...

  8. c语言普通变量间接访问,C语言学习笔记-指针

    野指针问题 野指针是没有指向地址的指针,也就是该指针指向的地址是随机的. 因为指针的指向地址是随机的,所以很有可能指向不可访问的弟子,导致程序崩溃,或者访问了不该访问的地址,导致影响其他功能使用 为了 ...

  9. c语言学习-使用指针求一个字符串的长度

    c语言使用指针求一个字符串的长度 程序流程图: 代码: #include<stdio.h> #define N 81 void main() {char str[N],*string=st ...

  10. C语言学习笔记---指针和数组

    数组是相同类型的数据集合,会在内存中占用连续的一块内存.而指针是存储的一个地址,在内存中不会占用连续的内存. 先来写一段测试代码 void fun(void) {int i;int num[10]={ ...

最新文章

  1. 字节、快手、阿里、腾讯这两年的广告推荐技术进展 | AICon
  2. CAlayer层的属性
  3. Newtonsoft 反序列化字符串
  4. 快速解决低版本Xcode不支持高版本iOS真机调试问题
  5. java netty rpc框架_Java编写基于netty的RPC框架
  6. 智能浪潮:增强时代来临
  7. python初步学习笔记(上)
  8. php 应用截图,PHP实现网页截图?
  9. wordpress企业站模板
  10. unity 查找所以物体_unity 查找物体的方法(包括隐藏物体)
  11. 文献检索(学术搜索)
  12. 第四次作业—四则运算
  13. 客户端和服务端简单开发
  14. 毕业设计之 - 基于深度学的图像修复 图像补全
  15. 白鹭引擎(Egret Engine )
  16. diy 单片机 自动浇花_自动浇花系统的设计及制作 基于Arduino
  17. DSO Framer
  18. 文献笔记--相关:无线通信、安全加密隐私
  19. 闭锁java_Java项目实践,CountDownLatch实现多线程闭锁
  20. 英特尔®以太网控制器E810介绍:面向5G核心网络

热门文章

  1. D触发器设计同步12进制加计数器
  2. 使用Instrumentation模拟点击屏幕
  3. 华为“天才少年”稚晖君被曝离职!两年前加入年薪百万起步的天才少年计划!...
  4. Apache Hue:安装步骤
  5. 15.说说你对slot的理解?slot使用场景有哪些?
  6. YD/T 1363.3-201X协议 通信局(站)电源、空调及环境集中监控管理系统
  7. js的 算法 和 数据结构
  8. id文本框适应文字_id怎么把字体框的尺寸缩小
  9. VLSI数字信号处理系统——第六章折叠
  10. matlab光通信,光纤通信课程设计matlab仿真源代码.doc