你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

vodi 函数(u32 *a)里的*a是要往函数输入什么?

[复制链接]
wrdt24435 提问时间:2018-8-25 17:34 /
阅读主题, 点击返回1楼
收藏 评论14 发布时间:2018-8-25 17:34
14个回答
sincomaster 回答时间:2018-8-27 17:18:09
wrdt24435 发表于 2018-8-27 13:32
看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型 ...

如我上图所示给楼主说下吧!
首先你第一段话就是错的括号这段)
(看了各位回复,首先u32型指针地址指的是4个地址的值意思吧?比如地址0x0000到0x0003的值是1,2,3,4,u32型指针能指向0x01020304的值)
你说U32指针能指向0x01,0x02,0x03,0x04,步进是1,这只能是char *p指针才是这样.因为char 是1个字节,

u32 *p的意思是:
声明一个u32类型的指针,指针指向的数据是u32类型,所以u32类型数据占4个字节(要注意不同的系统可能不一样)

我的第11行代码:
arr的地址就是arr[0]的地址,也就是0x001FFAA8
arr[1]地址是0x001FFAAC

注意parr这个(sizeof parr)也就是说指针变量本身占4个字节,(比如你的指针类型是占8个字节但指针变量本身还是4个字节,因为指针变量内存得是地址,不用8个字节这么大去存地址,除非地址很长//这句话你要好好理解一下,)

然后你看到没,&(*parr++)读出来的地址,0x001FFAA8(arr[0]的地址) 到0x001FFAAC(arr[1]的地址)指针加1就是跳转4个字节地址,

你的第一个问题1. 那要怎么指呢?也就是u32 *p=什么?是0x0000吗?)
这个就看函数调用了,像我的long *parr,我传的是(第20行代码)数组arr的首地址,所以long *parr = arr =arr[0]  = 1,但我32行代码用的是&(*parr++),用了%p来输出地址,如果是%d就输出值1,去掉&,

你的第二个问题其次也就是说数组a其实是指针地址,而a[x]则是一个变量,那么比如我想往void fn(u32 *a)这个函数输入a[2],是(u32 *)&a[2]这样输入吗?)
你要读a[2],正确的做法是*a+2(就不能使用*a++),你这种写法有点看不懂((u32*)&a[2])

你的第三个问题:
如果前面用了const修饰,那么后面的函数调用也用上吧,报错应该不至于吧,警告就会有,

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

tanic 回答时间:2018-8-27 17:24:53
1.u32 *p=?
这里?建议是指向变量地址
如 uint32_t a[10];
    uint32_t *p=a;
,不建议直接写地址如 0x20000000这种,因为ARM是精简指令集集必须寻址必须对齐,有的ram也只能对其访问
2.是的  
3.类型确实不一样,const修饰的是常量不可修改 没有const是变量可修改,强制转换不建议做,因为const修饰的应该不在ram中

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

stm1024 回答时间:2018-8-27 17:46:01
本帖最后由 stm1024 于 2018-8-27 18:23 编辑

我的C也学得很一般,针对你的问题,我还是一点点用例子来说明吧。我要说的都是老生常谈,基本上都是入门级的问题。
没什么技术含量,如果讲的不好甚至不对的地方,欢迎大家比较客气的批评指正。
1. 指针的自增
入门问题:指针的申明,到底是用
Type *x;
还是
Type* x;
答案是都可以,不过我个人更喜欢第二种。
  1. void f1(uint32_t* a)
  2. {
  3.     printf("Test For uint32_t\r\n");
  4.     do
  5.     {
  6.         printf("0x%08x\r\n",a);
  7.         a++;
  8.     }while(*a);
  9. }

  10. void f2(uint8_t* a)
  11. {
  12.     printf("Test For uint8_t\r\n");
  13.     do
  14.     {
  15.         printf("0x%08x\r\n",a);
  16.         a++;
  17.     }while(*a);
  18. }

  19. //测试一下这两段代码:
  20.     uint32_t a[]={7,6,5,4,3,2,1,0};
  21.     uint8_t b[]={7,6,5,4,3,2,1,0};
  22.     f1(a);
  23.     f2(b);
复制代码
运行的结果是:
2018-08-27_172953.jpg

f1和f2中同样都是a++,但是递增的效果并不一样,因为形参的类型分别是uint32_t*和uint8_t*的,所以指针的值,其实就是指向的对应数据类型的首地址,类型告诉了编译器该如何使用这个地址。




2.指针类型的转换
为了说明问题,我再写一个函数:
  1. void f3(uint8_t* a,uint8_t n)
  2. {
  3.     uint8_t i;
  4.     for(i=0;i<n;i++)
  5.         printf("%d\r\n",*(a+i));
  6. }
复制代码
然后代码是:
  1. f1(a);
  2.     f2((uint8_t *)a);
  3.     f3(a,32);
复制代码
运行效果呢?
2018-08-27_173813.jpg
可以看到,即使f2调用的时候做了强制类型转换,但是f2((uint8_t *)a);输出的第一个地址和f1(a)中的是一样的。
不过为什么第二函数只输入了一个值呢?因为在内存布局中,a数组的组织方式是07 00 00 00...
2018-08-27_174350.jpg
当到了第二个字节的时候,变成00,也就是'\0',函数提前退出了。
f3则直接打印32个字节的值,也有助于验证这个情况。
所以,要往哪个函数里面输入什么,取决于你要如何理解那一块内存区域,任何可访问的内存区域都是可以提供给这个函数的。
这个函数的意思是说,不管你那块内存区域是啥,我拿到内存首地址后,就按uint32_t,每四个字节作为一个单位来处理数据。
还有需要说明的是,有些控制器会有内存对齐的要求。


此外,对于一些内存操作的函数,如memcpy (void*, const void*, size_t);第一个数据类型是void*的指针类型。




评分

参与人数 1蝴蝶豆 +5 收起 理由
zero99 + 5

查看全部评分

stm1024 回答时间:2018-8-27 18:15:31
3. const指针和一般指针
    char a='x';
    const char* p=&a;
    *p='y';

这段代码是通过不了编译的,因为你的p是常常量指针,特点是,你可以修改指针指向的内存地址,但是不能修改指向地址的内容。
不过还是可以通过a来修改这个值。像string头文件中,很多函数,source char 都被定义为const char*,就是怕调用者瞎搞,把原始内容都给你破坏了。
和这个相反的还有char* const,指针常量,这个所指向的地址不能变,但是可以修改其中的内容。
还有常量指针常量const char* const类型,都不能改变……

12

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版