array variable used in printf function

在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.

时间: 2024-09-19 09:01:21

array variable used in printf function的相关文章

variable number of arguments function

有些时候可能需要函数能够接收任意个参数, 比方说fprintf()函数,  int fprintf(FILE *stream, const char *format, ...); ... 表示的是任意个数的参数. 类似的还有execl和execlp :        int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); 要写一个可以接收任意个参数

检测参数是否的为空的Function

因为所输入的参数类型不同,所以判断的方法也不一样.如何正确的判断参数是否为空? 具体的请看下文所示: <%'Check a variable isn't "empty"Function IsBlank(ByRef TempVar) 'by default, assume it's not blankIsBlank = False 'now check by variable typeSelect Case VarType(TempVar) 'Empty & NullCas

计算积分的function

昨天 GOOCAO搞活动 报名可获得免费上机 把报名的系统完成后需要对积分和上机时间进行计算:写了个function 收藏以后可能用的到   /**     * 积分     * 表:userbonus     * */$ChannelIntegralArr=array('threads'=>4,'comments'=>4); function IntagralConsersionTime($Integral,$disinfo=''){    $AccordTime=30;    $resul

javascript 二分法(数组array)_javascript技巧

在Javascript中,我们可以通过prototype关键字为对象添加新的属性或者是方法,下面是一个为Array对象添加二分法查找功能的方法: 复制代码 代码如下: Array.prototype.binarySearch = function(obj) { var value = 0; var left = 0; var right= this.length; while(left <= right) { var center = Math.floor((left+right)/2); if

JavaScript 5 新增 Array 方法实现介绍_javascript技巧

复制代码 代码如下: /*! * jLip JavaScript Library v0.1 * * Copyright 2012, Lip2up (lip2up@qq.com) * Just for free use, NO LICENSE */ (function() { function extend(target, props) { for (var m in props) { if (target[m] === undefined) target[m] = props[m]; } } v

浅析JavaScript中的array数组类型系统_javascript技巧

前面的话 数组是一组按序排列的值,相对地,对象的属性名称是无序的.从本质上讲,数组使用数字作为查找键,而对象拥有用户自定义的属性名.javascript没有真正的关联数组,但对象可用于实现关联的功能 Array()仅仅是一种特殊类型的Object(),也就是说,Array()实例基本上是拥有一些额外功能的Object()实例.数组可以保存任何类型的值,这些值可以随时更新或删除,且数组的大小是动态调整的 除了对象之外,数组Array类型可能是javascript中最常用的类型了.而且,javasc

Array.prototype 的泛型应用分析_javascript技巧

题目 请说明下面语句的输出: 复制代码 代码如下: x = {shift:[].shift}; x.shift(); console.info(x.length); 如果你回答正确,那么说明你已经了解 Array 函数的泛型应用.在理解这到题目之前,我 我们首先要了解数组(Array)的 shift 定义. MDC 中已经对相关的说明描述得非常的清楚 复制代码 代码如下: shift is intentionally generic; this method can be called or a

Prototype Array对象 学习_prototype

复制代码 代码如下: Array.from = $A; (function() { //Array原型的引用     var arrayProto = Array.prototype, slice = arrayProto.slice,      //JS 1.6里面会有原生的forEach方法 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available function each(it

javascript-jquery中报Uncaught TypeError: pie is not a function

问题描述 jquery中报Uncaught TypeError: pie is not a function $(function(){ var name = new Array(); var value=new Array(); var count = new Array(); $.post( "BaseAction/SheetAction/ContributeSheetPie", function(data) { name=data.name; value=data.value;