4-18-1-使用指针交换数据、多线程参数传递、多线程通信、指针与数组

本文探讨了指针的基本操作,包括初始化、零指针的使用以及如何通过指针交换数据。同时,讲解了多线程环境下参数传递的方式,并深入分析了指针与数组的关系,强调了无类型指针的限制以及数组与指针在函数调用中的应用。此外,还提及了多线程通信的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、指针运算符

指针必须初始化

不可以取常量的地址,比如&1,或者&(a+1)(因为常量是在寄存器中产生)

const int num = 3;
//*(&num) = 10;//因为num是const int类型,所以不能使用指针直接修改
*(int*)&num = 10;//但是可以强制转化为变量类型,再通过指针修改
//不可以写成(int)num=10;//不允许强制转化数据类型,强制转化是在寄存器产生,无法读取到地址
int a = 10;
void *p =&a;
//printf("%d",*p);//无法确定指针类型
printf("%d",*(int *)p);//强制转化指针类型


不可以对变量取两次地址,比如&&a,&a在寄存器中产生,不可以取寄存器的地址

*a这样也是不允许的,*是对后面括号中的地址取出数值。a不是地址,应写为*(&a)

 

直接访问:a=3

间接访问:*p=&a;*p=3;

 

零指针(空指针):int*p=NULL;int *p=0;

p=NULL与未对p赋值不同。

用途:避免指针变量的非法引用;在程序中常作为状态比较

 

改变一个变量,需要变量的地址,

改变一个指针变量,需要指针变量的地址

 

数据交换

1、

void change1(inta, int b)//不能成功
{
       int temp = a;
       a = b;
       b = temp;
}

2、

int*pa=&a,*pb=&b;
scanf("%d%d",pa, pb);//可以直接给a,b赋值
 

3、

void change2(int*pa, int *pb) //
{
       int temp = *pa;
       *pa = *pb;
       *pb = temp;
}//指针*pa,*pb交换成功,a,b交换成功
 
change2(pa,pb);//可以成功

4、

void change3(int*pa, int *pb)//不能成功
{
       int *temp = NULL;
       *temp = *pa;
       *pa = *pb;
       *pb = temp;
}交换指针向量的值,指针数值交换,a,b没没交换
 

5、

void change4(int*pa, int *pb)//不能成功
{
       int *temp = NULL;
       temp = pa;
       pa = pb;
       pb = temp;
}//交换指针的地址交换,但是由于副本机制,这里的pa,pb并不是主函数里面的pa,pb


2、多线程参数传递

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#include<Windows.h>
 
voidrun(void*p)
{
       int *px = p;
       char str[100] = { 0 };
       sprintf(str, "hello%d", *px);
       MessageBoxA(0, str, "world",0);
}
voidmain()
{
       /*for (int i = 0; i < 10; i++)
       {
              HANDLE win=_beginthread(run, 0,&i);//顺序
              WaitForSingleObject(win,INFINITE);
       }*/
       int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
       for (int i = 0; i < 10; i++)
       {
              HANDLE win = _beginthread(run, 0,&i);//很多重复数字,乱序
              HANDLE win = _beginthread(run, 0,&a[i]);//没有重复数据,乱序
       }
       system("pause");
}


 

3、指针与数组

       int num = 0;
       int *p = #
       printf("%p,%p", p, p + 1);//p+1等价于p+sizeof(*p)*1
指针运算与指针类型密切相关

 

没有明确类型的指针,不能进行指针运算

指针的加法,指针+整数

指针的减法,指针+整数,指针减去一个指针

       int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
       int *p1 = &a[0];
       printf("%d\n",*(p1+4));//a[4]  5
       int *p2 = &a[3];
       printf("%d,%d\n", *(p2 +4),*(p2-3));//a[3+4]  8
       printf("%d", p2 - p1);//3  (地址-地址)/sizeof(类型)
       printf("a=%p,&a=%p\n", a,&a);// 同一个地址00b9fd9c
       printf("a=%p,&a=%p\n", a,a+1);  //00b9fd9c 00b9fda0 相差4  a代表数组第一个元素的地址
       printf("a=%p,&a=%p",&a, &a + 1);//00b9fd9c 00b9fdc4 相差40(数组类型大小) 

数组与指针

    

   int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
   //int *p = a;//a是int类型,a表示数组第一个元素的地址
   //int *p =&a;//可能会出错

  //a++常量指针    

  for (int *p = a; p < a + 10; p++)
       {
              printf("%d,%p\n", *p,p);//输出数组a中的值
       }

 

函数与数组指针

#include<stdio.h>
#include<stdlib.h>
void test(inta[10])//等价于int *p,替换后只需将函数中所有的a替换为p
{
       printf("\nmain=%d\n",sizeof(a));//4
       for (int *px = a; px < a + 10; px++)
       {
              *px = 12;
              printf("%d,%p\n", *px,px);
       }
}
void main()
{
       int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
       //int *p = a;//a是int类型,a表示数组第一个元素的地址
       //int *p =&a;//可能会出错
       printf("\nmain=%d\n",sizeof(a));//40
 
       test(a);//这里的a就是数组第一个元素的地址,对应指针含义
       //数组在函数里面没有副本机制,而会退化为指针
       printf("\nmain");
       for (int *px = a; px < a + 10; px++)
       {
              printf("%d,%p\n", *px,px);//函数里面更改后,主函数里面的数组也会变化
       }
       system("pause");
}

数组大小

       int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
       printf("a=%p,&a=%p", a,&a);//一个地址
       printf("\n*a=%d,*&a=%d\n",sizeof(*a), sizeof(*&a));//4,40
       printf("\nmain=%d\n",sizeof(a));//40 {int b;*(&b)} 相当于把a当作*(&a)解析
 


 

4、多线程查找与线程通信

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#include<Windows.h>
#include<time.h>
#define M 100
#define N 10
isfind= 0;//线程通信
struct findinfo
{
       int *pstart;//开始
       int length;//长度
       int findnum;//查找的数据
       int id;//线程编号
};
void findit(void*p)
{
       struct findinfo *ps = p;//保存地址
       printf("线程%d开始查找\n", ps->id);
       for (int *pf = ps->pstart; pf <ps->pstart + ps->length; pf++)
       {
              if (isfind== 1)//若需要找到所有数据,注释此处
              {
                     printf("线程%d结束查找,其他线程已经找到\n", ps->id);
                     return;
              }
              if (*pf == ps->findnum)//相等
              {
                     printf("线程%d结束查找,找到数据%d地址%p\n", ps->id, *pf, pf);
                     isfind= 1;//
                     return;//若需要找到所有数据,注释此行
              }
              Sleep(500);//假设查找一个数据需要0.5秒
       }
       printf("线程%d结束查找,没有找到\n", ps->id);
}
void main()
{
       int a[M] = { 0 };
       time_t ts;
       unsigned int data = time(&ts);
       srand(data);
       for (int i = 0; i < M; i++)
       {
              a[i] = rand() % 100;
              printf("%4d", a[i]);
              if ((i + 1) % 10 == 0)
              {
                     printf("\n");
              }
       }
       int num=0;
       scanf("%d", &num);
       struct findinfo info[N];
       if(M%N==0)
       {
              for(int i = 0; i < N; i++)
              {
                     info[i].pstart= a + M/N * i;//首地址
                     info[i].length = M/N;
                     info[i].id = i;
                     info[i].findnum = num;
                     _beginthread(findit, 0, &info[i]);//调用线程
              }
       }
       else
       {
              for (int i = 0; i < N-1; i++)
              {
                     info[i].pstart= a + M/(N-1) * i;//首地址
                     info[i].length = M/(N-1);
                     info[i].id = i;
                     info[i].findnum = num;
                     _beginthread(findit, 0, &info[i]);//调用线程
           }
              int i=N-1;
              info[i].pstart = a + M/(N-1) *i;//首地址
              info[i].length= M%(N-1);
              info[i].id= i;
              info[i].findnum= num;
              _beginthread(findit, 0,&info[i]);
       }
       system("pause");
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值