前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言中常见指针问题集解答

C语言中常见指针问题集解答

作者头像
Linux兵工厂
发布2023-02-28 13:37:49
5370
发布2023-02-28 13:37:49
举报
文章被收录于专栏:Linux兵工厂

1. 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题?

代码语言:javascript
复制
char *p; 
*p = malloc(10);

答:你所声明的指针是p, 而不是*p, 当你操作指针本身时你只需要使用指针的名字即可:cp = malloc(10);当你操作指针指向的内存时,你才需要使用*作为间接操作符:*p = ’H’;

2. *p++自增p还是p所指向的变量?

答:后缀 ++ 和 -- 操作符本质上比前缀操作的优先级高, 因此 *p++*(p++) 等价, 它自增 p 并返回 p 自增之前所指向的值。要自增 p 指向的值, 使用(*p)++, 如果副作用的顺序无关紧要也可以使用 ++*p

3. 我有一个char*型指针正巧指向一些int型变量,我想跳过它们。为什么如下的代码不行?

代码语言:javascript
复制
((int *)p)++;

答:在 C 语言中, 类型转换意味着 “把这些二进制位看作另一种类型, 并作相应的对待”; 这是一个转换操作符, 根据定义它只能生成一个右值 (rvalue)。而右值既不能赋值, 也不能用 ++ 自增。(如果编译器支持这样的扩展, 那要么是一个错误, 要么是有意作出的非标准扩展)

代码语言:javascript
复制
// 要达到你的目的可以用
p = (char *)((int *)p + 1);

// 或者,因为 p 是 char * 型, 直接用
p += sizeof(int);

//但是, 在可能的情况下, 你还是应该首先选择适当的指针类型, 而不是一味地试图李代桃僵。

4. 我有个函数,它应该接收并初始化一个指针

代码语言:javascript
复制
void f(int *ip) 
{ 
    static int dummy = 5; 
    ip = &dummy;
}

但是当我如下调用时,调用者的指针却没有任何变化。

代码语言:javascript
复制
int *ip;
f(ip);

答:你确定函数初始化的是你希望它初始化的东西吗?请记住在 C 中, 参数是通过值传递的。被调函数仅仅修改了传入的指针副本。你需要传入指针的地址 (函数变成接受指针的指针), 或者让函数返回指针。

5. 我能否用void**指针作为参数, 使函数按引用接收一般指针?

答:不可以。C中没有一般的指针的指针类型。void*可以用作一般指针只是因为当它和其它类型相互赋值的时候, 如果需要, 它可以自动转换成其它类型; 但是, 如果试图这样转换所指类型为void*之外的类型void** 指针时, 这个转换不能完成。

6. 我有一个函数 extern int f(int *); 它接受指向 int 型的指针。我怎用引用方式传入一个常数?下面这样的调用似乎不行

代码语言:javascript
复制
f(&5);

答:在 C99 中, 你可以使用 “复合常量”:f((int[]){5});在C99之前,你不能直接这样做;你必须先定义一个临时变量,然后把它的地址传给函数:

代码语言:javascript
复制
int five = 5;
f(&five);

7. C有“按引用传递”吗?

答:真的没有。严格地讲,C总是按值传递。你可以自己模拟按引用传递, 定义接受指针的函数,然后在调用时使用 & 操作符。事实上,当你向函数传入数组时,编译器本质上就是在模拟按引用传递。但是 C 没有任何真正等同于正式的按引用传递或 C++ 的引用参数的东西。另一方面, 类似函数的预处理宏可以提供一种“按名称传递”的形式。

8. 我看到了用指针调用函数的不同语法形式。到底怎么回事?

答:最初, 一个函数指针必须用 * 操作符 (和一对额外的括弧) “转换为” 一个 “真正的” 函数才能调用:

代码语言:javascript
复制
int r, func(), (*fp)() = func;
r = (*fp)();

而函数总是通过指针进行调用的, 所有 “真正的” 函数名总是隐式的退化为指针。这个推论表明无论 fp 是函数名和函数的指针r = fp();ANSI C 标准实际上接受后边的解释,这意味着 * 操作符不再需要, 尽管依然允许。

9. 我怎样把一个 int 变量转换为 char * 型?我试了类型转换, 但是不行

答:这取决于你希望做什么。如果你的类型转换不成功, 你可能是企图把整数转为字符串。如果你试图把整数转换为字符,参考如下:

代码语言:javascript
复制
在 C 语言中字符用它们的字符集值对应的小整数表示。因此, 你不需要任何转换函数,如有你有字符, 你就有它的值。数字字符和它们对应的 0-9 的数字之间相互转换时, 加上或减去常数 ’0’, 也就是说, ’0’ 的字符值。

如果你试图让一个指针指向特定的内存地址,参考如下:

代码语言:javascript
复制
// 设置一个适当类型的指针取正确的值, 使用明示的类型重制, 以保证编译器知道这个不可移植转换是你的意图:

unsigned int *magicloc = (unsigned int *)0x12345678;

那么, *magiloc 就指向你所要的地址。 如果地址是个内存映射设备的寄存器,你大概需要使用限定词 volatile 。MS-DOS下, 在和段、偏移量打交道时, 你会发现像MK FP这类宏非常好用。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux兵工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题?
  • 2. *p++自增p还是p所指向的变量?
  • 3. 我有一个char*型指针正巧指向一些int型变量,我想跳过它们。为什么如下的代码不行?
  • 4. 我有个函数,它应该接收并初始化一个指针
  • 5. 我能否用void**指针作为参数, 使函数按引用接收一般指针?
  • 6. 我有一个函数 extern int f(int *); 它接受指向 int 型的指针。我怎用引用方式传入一个常数?下面这样的调用似乎不行
  • 7. C有“按引用传递”吗?
  • 8. 我看到了用指针调用函数的不同语法形式。到底怎么回事?
  • 9. 我怎样把一个 int 变量转换为 char * 型?我试了类型转换, 但是不行
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档