在C中, array变量和指针极其相似.

指针加减运算, 首先需要知道指针类型, 类型占用的字节数, 如int *的指针, 加1 则表示地址加4字节(假设32位的机器int占4字节);
如果是char * 的指针, 指针变量加1则表示地址加1字节(char 占1个字节).
例子1 :

#include <stdio.h>
#include <stdlib.h>int main() {
char a[10] = "abcdefg";
printf("a[0]:%i\n",a[0]);
printf("a[0]:%c\n",a[0]);
printf("a:%s\n",&a[0]);
printf("a:%s\n",a);
printf("a<<1:%s\n",&a[1]);
printf("addr(a):%p\n",a);
printf("addr(a[0]):%p\n",&a[0]);
return 0;
}
gcc -O3 -Wall -Wextra -Werror -g ./l.c -o l && ./l
a[0]:97
a[0]:a
a:abcdefg
a:abcdefg
a<<1:bcdefg
addr(a):0x7fff7f92b310
addr(a[0]):0x7fff7f92b310
从地址上看array变量应该在stack里面, 属于高位地址. 因为array定义后无法改变它指向的地址. 用于指向array创建时分配的空间的首地址.
例子2 :

#include <stdio.h>
#include <stdlib.h>int main() {
char *a = "abcdefg";
printf("a[0]:%i\n",a[0]);
printf("a[0]:%c\n",a[0]);
printf("a:%s\n",&a[0]);
printf("a:%s\n",a);
printf("a<<1:%s\n",&a[1]);
printf("addr(a):%p\n",a);
printf("addr(a[0]):%p\n",&a[0]);
return 0;
}
gcc -O3 -Wall -Wextra -Werror -g ./l.c -o l && ./l
a[0]:97
a[0]:a
a:abcdefg
a:abcdefg
a<<1:bcdefg
addr(a):0x40063a
addr(a[0]):0x40063a
从地址上看指针变量应该在constants里面, 属于低位地址. 因为指针指向的是"abcdefg"这个常量的首地址, 字符串是放在内存的constants区域的.
constants区域不能改变. 
另外指针加减算法得到的结果还是指针, 但是如果要得到结果指向的内容可以使用*, 或者[]. 如下 : 
printf 函数, 在打印%s时, 对应的参数必须是char *. 在打印%c 和 %i 时对应的参数必须是int. 打印%p时对应的参数必须是指针.

另外需要注意的几点 :

1. 调用函数时, 传递的是值, 而不是传入的变量本身, 所以如果要修改传入的变量的值, 使用指针传递是比较好的方法, 因为拷贝指针的值指向的是想修改的变量地址.
2. 通过指针修改变量的值, 可使用* 或者[]. 如上图.
例如 :

#include <stdio.h>
#include <stdlib.h>char a[] = "abc";void exchange1(char * i) {char x;x = i[0];i[0] = i[2];i[2] = x;
}void exchange2(char * i) {char x;x = *i;*i = *(i+2);*(i+2) = x;
}int main() {printf("old a:%s\n", a);exchange1(a);printf("new1 a:%s\n", a);exchange2(a);printf("new2 a:%s\n", a);return 0;
}
gcc -O3 -Wall -Wextra -Werror -g ./l.c -o l && ./l
old a:abc
new1 a:cba
new2 a:abc

3. 由于char * a = "ABC" 这种方式定义的指针, 字符串是存储在constants区域的, 无法修改. 所以一般这种定义可以改为const char * a = "ABC"/

那么在代码中如果出现a[0]="O"; 这种语句时编译器会报错. 更容易理解.

从内存地址可以看出加了const和未加const定义的变量, 他们存放的内存区域是不一样的.

#include <stdio.h>
#include <stdlib.h>const char a[] = "abc";
const char b[] = "abc";
char c[] = "abc";
char d[] = "abc";
char *e = "abc";
char *f = "abc";int main() {printf("addr a:%p\n", a);printf("addr b:%p\n", b);printf("addr c:%p\n", c);printf("addr d:%p\n", d);printf("addr e:%p\n", e);printf("addr f:%p\n", f);return 0;
}
gcc -O3 -Wall -Wextra -Werror -g ./l.c -o l && ./l
addr a:0x40065e
addr b:0x400662
addr c:0x600910
addr d:0x600914
addr e:0x40065a
addr f:0x40065a

同时你会发现constant "abc". 只放了一份. e和f指向同一地址.

4. Q: I still don’t understand why an array variable isn’t stored in memory. If it exists, surely it lives somewhere?
A: When the program is compiled, all the references to array variables are replaced with the addresses of the array. 
So the truth is that the array variable won’t exist in the final executable. That’s OK because the array variable will never be needed to point anywhere else.
Q: If I set a new array to a string literal, will the program really copy the contents each time?
A: It’s down to the compiler. The final machine code will either copy the bytes of the string literal to the array, or else the program will simply set the values of each character every time it reaches the declaration.
Q: You keep saying “declaration.” What does that mean?
A: A declaration is a piece of code that declares that something (a variable, a function) exists. A definition is a piece of code that says what something is. If you declare a variable and set it to a value (e.g., int x = 4;), then the code is both a declaration and a definition.

array variable used in printf function相关推荐

  1. Vue——[Props with type Object/Array must use a factory function to return the default value.]解决方案

    问题描述 [Vue warn]: Invalid default value for prop "weekTable": Props with type Object/Array ...

  2. 【C++】char uchar string stringstream queue array vector set map std::function std::bind

    文章目录 cout 防止使用科学计数法 一维数组的三种初始化方法 二维数组 vector作为参数的三种传参方式 vector 的 reserve resize set std::map std::pa ...

  3. 【JavaScript框架封装】使用Prototype给Array,String,Function对象的方法扩充

    版权声明:本文为博主原创文章,未经博主允许不得转载.更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/ ...

  4. Object、Function、String、Array原生对象扩展方法

    JavaScript原生对象的api有些情况下使用并不方便,考虑扩展基于Object.Function.String.Array扩展,参考了prototype.js的部分实现,做了提取和修改,分享下: ...

  5. c语言strcpy错误,C语言中的Printf和Strcpy错误。

    Here i wrote a piece of code. A function to add long numbers (used strings to represent numbers). 这里 ...

  6. 深入理解JavaScript内部原理(5): function

    本文是翻译http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#introduction 概要 In this article we w ...

  7. c语言自建一个窗口,C语言 手把手教你写个自定义printf

    一个简单的例子 __printf (const char *format, ...) { va_list arg; int done; va_start (arg, format); done = v ...

  8. c语言printf输出语句_C语言中另一个printf()语句中的printf()语句

    c语言printf输出语句 A printf() function is a standard library function, that is used to print the text and ...

  9. 【Tensorflow教程笔记】常用模块 tf.function :图执行模式

    基础 TensorFlow 基础 TensorFlow 模型建立与训练 基础示例:多层感知机(MLP) 卷积神经网络(CNN) 循环神经网络(RNN) 深度强化学习(DRL) Keras Pipeli ...

最新文章

  1. 蓝桥杯第七届决赛真题大全题解(java版本)
  2. 报名 | 东南大学周张泉:基于知识图谱的推理技术
  3. 用计算机答题答案提交后能否改错,南京晓庄计算机操作系统习题库含答案全1-5章...
  4. 农历控件源码(C#)
  5. 2017.7.18可变/不可变类型,符号运算及其流程控制
  6. STM32F0使用LL库实现DMA方式AD采集
  7. 软通动力华为java机考题库_华为机考笔试刷题-java-1
  8. SSH远程管理,构建密钥对验证的SSH体系,设置SSH代理功能。
  9. DropDownList 实现分页不包含选择值
  10. 快解析:用友T+异地访问解决方案
  11. SQL2008 SQLExpress数据库存满处理
  12. WebDriver - 伪浏览器PhantomJs(ghost driver) HtmlUnit
  13. 地图飞线图 echart+高德地图实现
  14. Python加密word文档
  15. 剑魂之刃登录显示服务器异常,剑魂之刃新手问题汇总
  16. mysql8时区设置_解决MySQL8.0时区的问题步骤
  17. 确定你到底喜欢什么事
  18. 使用echars绘制股票图
  19. zenmap扫描ip段_zenmap端口扫描工具(ip端口扫描器)V7.71 最新版
  20. 已知稀疏多项式C语言版,一元稀疏多项式计算器C语言课程设计

热门文章

  1. Windows消息机制概述
  2. VS2010快捷键大全----养成良好的习惯
  3. (转)CentOS 和 Ubuntu 下的网络配置
  4. Guava学习笔记(1)--安全地使用null(Using and avoiding null)
  5. 第10组-通信2班-011-抓包分析
  6. Java练习 SDUT-3338_计算各种图形的周长(接口与多态)
  7. FFmpeg Android 学习(一):Android 如何调用 FFMPEG 编辑音视频
  8. 解决vue在ie9中的兼容问题
  9. 【深度学习之美】激活引入非线性,池化预防过拟合(入门系列之十二)
  10. Lenovo E47A Ubuntu闪屏解决办法