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创建时分配的空间的首地址.
array variable used in printf function - 德哥@Digoal - The Heart,The World.
 

例子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区域的 .
array variable used in printf function - 德哥@Digoal - The Heart,The World.
 
constants区域不能改变. 

另外指针加减算法得到的结果还是指针, 但是如果要得到结果指向的内容可以使用*, 或者[]. 如下 : 
array variable used in printf function - 德哥@Digoal - The Heart,The World.
 

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.
目录
相关文章
|
安全 C语言
警告 1 warning C4996: ‘scanf‘: This function or variable may be unsafe.
警告 1 warning C4996: ‘scanf‘: This function or variable may be unsafe.
|
安全
VS2019 error C4996: ‘scanf‘: This function or variable may be unsafe 错误
VS2019 error C4996: ‘scanf‘: This function or variable may be unsafe 错误
517 0
VS2019 error C4996: ‘scanf‘: This function or variable may be unsafe 错误
|
C++
warning C4996 sprintf This function or variable may be unsafe
warning C4996 sprintf This function or variable may be unsafe
149 0
|
计算机视觉
opencv出错:error: (-213:The function/feature is not implemented) Unknown/unsupported array type
opencv出错:error: (-213:The function/feature is not implemented) Unknown/unsupported array type
632 0
组件是默认值报错:Props with type Object/Array must use a factory function to return the default value
组件是默认值报错:Props with type Object/Array must use a factory function to return the default value
组件是默认值报错:Props with type Object/Array must use a factory function to return the default value
VS2017报错:严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C4996 'strcpy': This function or variable may be unsafe. Consid
VS2017报错:严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C4996 'strcpy': This function or variable may be unsafe. Consid
934 0
|
存储 JavaScript 前端开发
【JavaScript框架封装】使用Prototype给Array,String,Function对象的方法扩充
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81055991 ...
1224 0

热门文章

最新文章

  • 1
    Java 中数组Array和列表List的转换
    590
  • 2
    JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
    553
  • 3
    通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化,reduce()的使用详解(附实际应用代码)
    1324
  • 4
    通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
    391
  • 5
    通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
    244
  • 6
    多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解
    157
  • 7
    别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
    181
  • 8
    Array.forEach实战详解:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提高Array.forEach的性能
    126
  • 9
    深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
    442
  • 10
    JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
    824