C语言运算符优先级表(由上至下, 优先级依次递减)

运算符 结合性
()  []  ->  . 自左向右
 !  ~  ++  --  -  (type)  *  &  sizeof 自右至左
*  /  %  自左向右
+  -  自左向右
<<  >>  自左向右
<  <=  >  >=  自左向右
==  !=  自左向右
自左向右
自左向右
自左向右
&&  自左向右
||  自左向右
?:  自右至左
assignments  自右至左 
自左向右

(来自C陷阱与缺陷)



对于( )  或者  [ ] 的优先级是最高的

于是对于  *p[2]  结合的方式应该是   *(p[2])    对于  (*p)[2]  显然结合方式是括号中的 *p 优先于 [2]

具体

char *p[2]  表示p是一个存储指向char类型数据的指针的数组

char (*p)[2]  则表示*p是一个拥有两个char类型元素的数组,那么p则表示指向这个数组的指针

void test(){
char *p1[];
char (*p2)[];
printf("p1----%d\n", sizeof(p1));
printf("p2----%d\n", sizeof(p2));
return;
}

得到的结果是

可以看到p1表示的是一个拥有两个(char *)类型的数组,一个指针占有4个字节,俩个当然是8个字节

而p2仅仅就只是一个指针,只占有4个字节

常用用途


  • 对于  *p[]

在main函数的参数中有使用到,其中的 char *argv[]的argv就是一个指针数组,用来存储函数调用时传进来可变个数的参数

(详细:利用 gdb 探究main(int argc, char *argv[]){} 中的char *argv[]

int main(int argc, char *argv[])
{
something you want to do;
return ;
}

比如可以这样

char *pp[] = {"hello", "world",};

pp[0]存储字符串"hello"的第一个字符的地址,pp[1] 存储字符串"world"的第一个字符的地址

printf("%s\n", pp[]);

将会打印出 hello


  • 对于  (*p)[]

无疑就是可以作为二维数组的引用

其实二维数组的本质也是一维数组,那么当我们定义一个二维数组的时候为什么不可以使用像引用一维数组的那样的指针来引用二维数组呢?

错误样例

void arrays(){
int nums[][] = {};
int *pn = nums;
}

原因就是二维数组其实就是一个成员是一维数组的一维数组,所以它的类型是应该是数组类型

而这里的pn所指的类型是int,就会出现类型不匹配的问题

正确的方式是

void arrays(){
int nums[][] = {};
int (*p_nums)[] = nums;
}

这样的p_num是指向类型为数组的指针,与nums的类型相匹配


补充

二维数组在内存中的存储问题

示例代码

#include <stdio.h>
#include <stdlib.h> int main()
{
/*定义char类型便于观察地址,因为char只占一个byte*/
char chars[][] = {{, , , }, {, , , }, {, , , },};
printf("-------------------------------------------------------------------\n\n"); for(int i = ; i < ; ++i){
for(int j = ; j < ; ++j){
printf("%5d(%d)", chars[i][j], (int)&chars[i][j]);
}
printf("\n");
} printf("\n-------------------------------------------------------------------\n"); printf("%d\n", sizeof(chars));
printf("%d\n", (int)chars);
printf("%d\n", (int)(chars + ));/*移动了4个元素,行移动*/ printf("-------------------------------------------------------------------\n"); printf("%d\n", sizeof(chars[]));
/*可以看作是一维数组的第一个元素的地址 形如 一维数组中的 &array[0]*/
printf("%d\n", (int)&chars[]);
/*可以看作就是一维数组里的第一个元素是数组,它相当于一个数组名表示数组地址 形如 array*/
printf("%d\n", (int)chars[]); printf("-------------------------------------------------------------------\n"); return ;
}

输出

得到的结果以及代码注释已经可以说明一些问题了,就不再重复


本节完......

C语言中的 *p[2] 与 (*p)[2] 的截然不同的更多相关文章

  1. JAVA语言中的修饰符

    JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...

  2. Java语言中的面向对象特性总结

    Java语言中的面向对象特性 (总结得不错) [课前思考]  1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?  2. 面向对象编程的特性有哪三个?它们各自又有哪些特性?  3. 你知 ...

  3. python语言中的编码问题

    在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...

  4. 在C语言中利用PCRE实现正则表达式

    1. PCRE简介 2. 正则表达式定义 3. PCRE正则表达式的定义 4. PCRE的函数简介 5. 使用PCRE在C语言中实现正则表达式的解析 6. PCRE函数在C语言中的使用小例子 1. P ...

  5. C语言中函数声明实现的位置

    在学习C语言的时候我遇到了这么个事情,因为之前先学习的C#,在C#编译器中,函数的声明位置不会影响编译的结果,但是在C语言中却发生了错误 先看一段代码: #include <stdio.h> ...

  6. C语言中的栈和堆

    原文出处<http://blog.csdn.net/xiayufeng520/article/details/45956305#t0> 栈内存由编译器分配和释放,堆内存由程序分配和释放. ...

  7. 在易语言中调用MS SQL SERVER数据库存储过程方法总结

    Microsoft SQL SERVER 数据库存储过程,根据其输入输出数据,笼统的可以分为以下几种情况或其组合:无输入,有一个或多个输入参数,无输出,直接返回(return)一个值,通过output ...

  8. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  9. Coursera-Getting and Cleaning Data-week4-R语言中的正则表达式以及文本处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html Thursday, January 29, 2015 补上第四周笔记,以及本次课程总结. 第四周 ...

随机推荐

  1. 解题:HDU 5868 Different Circle Permutation

    题面 先往上套Burnside引理 既然要求没有$\frac{2*π}{n}$的角,也就是说两个人不能挨着,那么相当于给一个环黑白染色,两个相邻的点不能染白色,同时求方案数.考虑$n$个置换子群,即向 ...

  2. Qtree4——动态点分治

    题目描述 给出一棵边带权的节点数量为n的树,初始树上所有节点都是白色.有两种操作: C x,改变节点x的颜色,即白变黑,黑变白 A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为 ...

  3. Request URI Too Long

    如上图所示,URL传參长度限制,改为Post参数提交就好了.

  4. swift学习笔记3

    1.在 Swift 中,枚举类型是一等(first-class)类型.它们采用了很多在传统上只被类(class)所支持的特性,例如计算型属性(computed properties),用于提供枚举值的 ...

  5. Ubuntu 16.04开机自启Nginx简单脚本

    本文要记述的是最简单的Ubuntu下开机自启 nginx的脚本 这里将nginx装在了/usr/local/nginx目录下,nginx本身没有注册成服务,所以直接使用服务开机自启是不行的,除非自己写 ...

  6. VMware Linux 下 Nginx 安装配置 - Tomcat 配置 (二)

    准备工作 相关浏览: VMware Linux 下 Nginx 安装配置 (一) 1. 选在 /usr/local/ 下创建 softs 文件夹,通过 ftp 命令 把 apache-tomcat-7 ...

  7. 如何使用 grunt

    1>. 首先要有nodejs环境, 至少0.8.0版本: 2>. 转到 项目文件夹下: >npm install –g grunt-cli >npm init #生成一个基本的 ...

  8. 关于 xcode5 的no matching provisioning profiles found

    CHENYILONG Blog 关于 xcode5 的no matching provisioning prof- about the question in xcode5 "no matc ...

  9. HDU 4508 湫湫系列故事——减肥记I (完全背包)

    题意:有n种食物,每种食物可以给湫湫带来一个幸福感a,同时也会给她带来b的卡路里的摄入,然后规定她一天摄入的卡路里的量不能超过m,一共有n种食物,问可以得到的 最大的幸福感是多少? 解题报告:一开始以 ...

  10. Ubuntu接显示器问题

    1.Could not apply the stored configuration for monitors 解决办法:Ubuntu在开机进入桌面的时候,会调用gnome-setting-deamo ...