the difference between pointer and array (and variable)

本文详细解析了一段使用C语言编写的代码片段,重点讲解了内存分配、指针操作以及数组与指针之间的关系。通过代码实例,展示了如何在内存中分配变量、指针和数组的空间,并阐述了编译器如何处理指针和数组名以实现内存的高效利用。文章还特别强调了指针与数组元素之间的转换,以及指针常量与普通指针的区别,帮助读者更好地理解C语言中内存管理的核心概念。
/********************************test,c***********************
song 
8.13
*************************************************************/
#include<stdio.h>  
int i=6;
int cc[9]={1,2,3,4,5,6,7,8,9};
int * const pa=cc;//注意const的位置:不是const int * pa,
int *  ppa=cc;
int bb[2][3]={{0x50,0x51,0x52},{0x53,0x54,0x55}};

int main()  
{

i=3;
i=3;
*(cc+1)=6;
*(pa+1)=8;
*(ppa+1)=9;
*(*(bb+1)+1)=0x99;
i=2;
i=2;

printf("%x\n",i);
printf("%x\n",*(cc+1));
printf("%x\n",*(pa+1));
printf("%x\n",*(ppa+1));
printf("%x\n",*(*(bb+1)+1));

printf("%x\n",cc);
printf("%x\n",pa);
printf("%x\n",ppa);
printf("%x\n",bb);

printf("%x\n",&i);
printf("%x\n",&cc);
printf("%x\n",&pa);
printf("%x\n",&ppa);
printf("%x\n",&bb);
}
[root@localhost mmap]# ./test
2
9
9
9
99
8049800
8049800
8049800
8049828
80497e0
8049800
8048634
8049824
8049828
//print sections
[root@localhost mmap]# readelf -S test
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [15] .rodata           PROGBITS        08048628 000628 000014 00   A  0   0  4
  [24] .data             PROGBITS        080497c0 0007c0 000080 00  WA  0   0 32
//print symblols
[root@localhost mmap]# readelf -s test
   Num:    Value  Size Type    Bind   Vis      Ndx Name
    46: 08048634     4 OBJECT  GLOBAL DEFAULT   15 pa
    53: 08049800    36 OBJECT  GLOBAL DEFAULT   24 cc
    57: 080497e0     4 OBJECT  GLOBAL DEFAULT   24 i
    62: 08049828    24 OBJECT  GLOBAL DEFAULT   24 bb
    65: 08049824     4 OBJECT  GLOBAL DEFAULT   24 ppa
[root@localhost mmap]# objdump -s test

Contents of section .rodata:
 8048628 03000000 01000200 00000000 00980408  ................
/*
the address of pa is starting from 8048634 ,length 4 bytes,it's content 
is "00980408" displaying as little endian
actually it is 08049800---the address of cc
*/
Contents of section .data:
 80497c0 00000000 00000000 00000000 00000000  ................
 80497d0 00000000 00000000 00000000 00000000  ................
 80497e0 06000000 00000000 00000000 00000000  ................
 80497f0 00000000 00000000 00000000 00000000  ................
 8049800 01000000 02000000 03000000 04000000  ................
 8049810 05000000 06000000 07000000 08000000  ................
 8049820 09000000 00980408 50000000 51000000  ........P...Q...
 8049830 52000000 53000000 54000000 55000000  R...S...T...U...
/*
the address of cc is starting from 08049800 ,4*9=36 bytes length ,we can see it's 
content is 1 2 3 4 5 6 7 8 9 from data section
the address of bb is starting from 08049828 , 4*2*3=24 bytes length
cotent is 50 51 52 53 54 55
the address of i is starting from 080497e0 , 4 bytes length,cotent is 6
the address of ppa is starting from 08049824 , the length and cotent are the same as pa
located in rodata section
*/

可用下图表示变量,指针,数组的内存分分配


[root@localhost mmap]# objdump -S test
080483c4 <main>:
 80483c4:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 80483c8:	83 e4 f0             	and    $0xfffffff0,%esp
 80483cb:	ff 71 fc             	pushl  -0x4(%ecx)
 80483ce:	55                   	push   %ebp
 80483cf:	89 e5                	mov    %esp,%ebp
 80483d1:	51                   	push   %ecx
 80483d2:	83 ec 14             	sub    $0x14,%esp
 80483d5:	c7 05 e0 97 04 08 03 	movl   $0x3,0x80497e0//i=3;
 80483dc:	00 00 00 
 80483df:	c7 05 e0 97 04 08 03 	movl   $0x3,0x80497e0//i=3;
 80483e6:	00 00 00 
/*$表示一个立即数,%表示一个寄存器,( )表示寄存器间接寻址
编译器将i用其地址0x80497e0替换掉
翻译为将立即数3移到内存单元0x80497e0*/
 80483e9:	b8 04 98 04 08       	mov    $0x8049804,%eax//*(cc+1)=6;
 80483ee:	c7 00 06 00 00 00    	movl   $0x6,(%eax)
/*
编译器将cc+1用cc+1所表示的地址值替换掉
cc+1-->8049800+4=8049804
编译器将*(cc+1)翻译为将计算出来的地址塞进累加器eax,
利用寄存器间接寻址将立即数6塞进内存单元8049804
*/
 80483f4:	a1 34 86 04 08       	mov    0x8048634,%eax//*(pa+1)=8;
 80483f9:	83 c0 04             	add    $0x4,%eax
 80483fc:	c7 00 08 00 00 00    	movl   $0x8,(%eax)
/*
编译器将pa用pa之地址替换下来
编译器将*(pa+1)翻译为将pa地址8048634塞进eax
执行+1操作,即eax=8048634+4=8048638
将立即数塞进8048638内存单元
*/
 8048402:	a1 24 98 04 08       	mov    0x8049824,%eax//*(ppa+1)=9;
 8048407:	83 c0 04             	add    $0x4,%eax
 804840a:	c7 00 09 00 00 00    	movl   $0x9,(%eax)
/*
同*(pa+1)=8;

可以看出,指针常量和指针都被编译器翻译成一样的代码,
数组名cc+1,cc[1]等都是编译器编译时执行的的运算
pa+1是程序运行时执行的运算
所以,数组名只是一个c语言的规定,用于编译器计算数组元素的地址值,
c语言在数组范畴规定了这么多的东西,要求我们按照他说的规范去写,然后他在编译的时候,直接套用
规范计算出实际地址,而不是在程序运行的时候去计算

指针常量和指针都是有一个32b的内存单元来装其值得
数组名没有
数组名在内存中更像是普通变量(的集合)
但是在c语言中,大部分场合,要将数组名"假想"作一个指针去用,
这是c语言规范,因为 编译时,是将数组名当做指针对待
比如将cc[1]先在内部译成*(cc+1)
这也就解释了指针也可以写成数组的形式,因为即使你写成了数组的形式(不管实际是数组还是指针)
,编译器还是会将其换成指针

一下来自 thq c程序设计
int *p;
int a[10];
p=&a[0](或p=a);
则
p+i,a+i都是a[i]的地址.a[i]也可写作p[i]
*(p+i),*(a+i)都是p+i或a+i指向的数组元素即a[i]的值
比如p+2,代表a[2]的地址,或说p[2]的地址


 
*/
 8048410:	b8 28 98 04 08       	mov    $0x8049828,%eax//*(*(bb+1)+1)=0x99;
 8048415:	83 c0 10             	add    $0x10,%eax
 8048418:	c7 00 99 00 00 00    	movl   $0x99,(%eax)
/*
8049828+12+4
*/
804841e:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;
 8048425:    00 00 00 
 8048428:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;
 804842f:    00 00 00 
 8048432:    a1 e0 97 04 08           mov    0x80497e0,%eax
 8048437:    89 44 24 04              mov    %eax,0x4(%esp)
 804843b:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048442:    e8 ad fe ff ff           call   80482f4 <printf@plt>
 8048447:    b8 04 98 04 08           mov    $0x8049804,%eax
 804844c:    8b 00                    mov    (%eax),%eax
 804844e:    89 44 24 04              mov    %eax,0x4(%esp)
 8048452:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048459:    e8 96 fe ff ff           call   80482f4 <printf@plt>
 804845e:    a1 34 86 04 08           mov    0x8048634,%eax
 8048463:    83 c0 04                 add    $0x4,%eax
 8048466:    8b 00                    mov    (%eax),%eax
 8048468:    89 44 24 04              mov    %eax,0x4(%esp)
 804846c:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048473:    e8 7c fe ff ff           call   80482f4 <printf@plt>
 8048478:    a1 24 98 04 08           mov    0x8049824,%eax
 804847d:    83 c0 04                 add    $0x4,%eax
 8048480:    8b 00                    mov    (%eax),%eax
 8048482:    89 44 24 04              mov    %eax,0x4(%esp)
 8048486:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 804848d:    e8 62 fe ff ff           call   80482f4 <printf@plt>
 8048492:    b8 28 98 04 08           mov    $0x8049828,%eax
 8048497:    83 c0 10                 add    $0x10,%eax
 804849a:    8b 00                    mov    (%eax),%eax
 804849c:    89 44 24 04              mov    %eax,0x4(%esp)
 80484a0:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 80484a7:    e8 48 fe ff ff           call   80482f4 <printf@plt>
 80484ac:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)
 80484b3:    08 
 80484b4:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 80484bb:    e8 34 fe ff ff           call   80482f4 <printf@plt>
 80484c0:    a1 34 86 04 08           mov    0x8048634,%eax
 80484c5:    89 44 24 04              mov    %eax,0x4(%esp)
 80484c9:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 80484d0:    e8 1f fe ff ff           call   80482f4 <printf@plt>
 80484d5:    a1 24 98 04 08           mov    0x8049824,%eax
 80484da:    89 44 24 04              mov    %eax,0x4(%esp)
 80484de:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 80484e5:    e8 0a fe ff ff           call   80482f4 <printf@plt>
 80484ea:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)
 80484f1:    08 
 80484f2:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 80484f9:    e8 f6 fd ff ff           call   80482f4 <printf@plt>
 80484fe:    c7 44 24 04 e0 97 04     movl   $0x80497e0,0x4(%esp)
 8048505:    08 
 8048506:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 804850d:    e8 e2 fd ff ff           call   80482f4 <printf@plt>
 8048512:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)
 8048519:    08 
 804851a:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048521:    e8 ce fd ff ff           call   80482f4 <printf@plt>
 8048526:    c7 44 24 04 34 86 04     movl   $0x8048634,0x4(%esp)
 804852d:    08 
 804852e:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048535:    e8 ba fd ff ff           call   80482f4 <printf@plt>
 804853a:    c7 44 24 04 24 98 04     movl   $0x8049824,0x4(%esp)
 8048541:    08 
 8048542:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 8048549:    e8 a6 fd ff ff           call   80482f4 <printf@plt>
 804854e:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)
 8048555:    08 
 8048556:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)
 804855d:    e8 92 fd ff ff           call   80482f4 <printf@plt>
 8048562:    83 c4 14                 add    $0x14,%esp
 8048565:    59                       pop    %ecx
 8048566:    5d                       pop    %ebp
 8048567:    8d 61 fc                 lea    -0x4(%ecx),%esp
 804856a:    c3                       ret    
 804856b:    90                       nop    
 804856c:    90                       nop    
 804856d:    90                       nop    
 804856e:    90                       nop    
 804856f:    90                       nop    



1. What is an IDE (Integrated Development Environment), and what are its main components? 2. What is the role of a compiler in the C++ development process? 3. What is the difference between source code (e.g., a .cpp file) and an executable file? 4. In the "Hello, World!" program, what is the purpose of the line #include <iostream>? 5. What is special about the main() function in a C++ program? 6. Why do computers fundamentally operate using the binary (base-2) system? 7. What is the base of the hexadecimal system? Why is it often used by programmers as a shorthand for binary numbers? 8. Explain the "triad" method for converting an octal number to binary. 9. Briefly describe the "division by 2" method for converting a decimal number to binary. 10. What is the decimal value of the binary number 1011? 1. What is the purpose of the std::cout object? Which header file must be included to use it? 2.What is the difference between an escape sequence like \n and a manipulator like std::endl? (Hint: Both create a new line, but they have a subtle difference). 3.How would you print the following text to the console, including the quotes and the backslash: He said: "The file is in C:\Users\"? 4.Is it possible to write an entire multi-line text output using only one std::cout statement? If yes, how? 5.What is a syntax error? Give an example of a syntax error from Task 2. (Task 2: Debugging The following program contains several syntax errors. Copy the code into your IDE, identify the errors, fix them, and run the program to ensure it works correctly. Incorrect Code: */ Now you should not forget your glasses // #include <stream> int main { cout << "If this text" , cout >> " appears on your display, cout << " endl;" cout << 'you can pat yourself on ' << " the back!" << endl. return 0; "; ) Hint: Pay close attention to comments, header files, brackets ({}), operators (<<), semicolons, and how strings and manipulators are written.) 1. What is the difference between variable declaration and initialization? 2.What will be the result of the expression 7 / 2 in C++? Why? 3.What will be the result of the expression 10 % 3? What is the main purpose of the modulus operator? 4. What is the purpose of std::cin and the >> operator? 5. A beginner tries to swap two integer variables a and b with the code a = b; b = a;. Why will this not work correctly? 1. What is an algorithm? Name the primary ways to represent an algorithm. 2.List the main flowchart symbols and explain their purpose. 3.What are the three fundamental types of algorithm structures? Briefly describe each. 4.In a branching algorithm, what determines the flow of execution? 5.What is the key characteristic of a linear algorithm? 6.When is a cyclic algorithm structure used?7. 8. 9. 7.Explain the purpose of a connector in a flowchart. 8.What is the difference between a predefined process block and a standard process block? 9.In the context of solving a quadratic equation algorithm, what condition must be checked before calculating the roots? Why? 1. What are the three main approaches to data input and output offered by C++? 2. What is the purpose of the SetConsoleOutputCP(65001) and SetConsoleCP(65001)
functions in the provided C++ program example? 3. Explain the difference between the cin and cout objects in Stream 1/0. 4. When using formatted 1/0, which header file must be included to use manipulators like setw and setprecision? 5. List three manipulators used for data output in C++ and briefly describe what each one does. 6. In Formatted I/0 using printf), what are the conversion specifications for a decimal integer and a real number in exponential form? 7. What is the difference in how the & (address-of) operator is used when inputting a value for an integer variable versus a string variable using the scanf() function? 8. Which Character I/O function is used to output a single character to the screen, and which is used to output a string? 9. Describe the syntax and function of the ternary operator in C++. 10. What is the difference between the logical AND (&&) and logical OR (I|) operators when combining multiple conditions? 11. When is the default label executed in a C++ switch statement? 12. What is the primary purpose of the break statement within a switch block? 1. What is the main purpose of using loops in programming? 2. Explain the key difference between the for, while, and do while loops. 3. What happens if you forget to include the increment/decrement statement in a while loop? 4. How can you interrupt an infinite loop during program execution? 5. What is the role of the setw() and setfill) manipulators in C++? 6. In a nested loop, how does the inner loop behave relative to the outer loop? 7. What is type casting, and why is it used in loop calculations? 8. How does the do while loop differ from the while loop in terms of condition checking? 9. What output formatting options can be used to align numerical results in columns? 10*. How would you modify a loop to skip certain iterations based on a condition? 1. List the six main biwise operators in C++ and explain the function of each. 2. Why cannot bitwise operations be applied to variables of floating-point type? 3. Explain the purpose of the << (left shift) and >> (right shift) operators. What is the typical effect on the decimal value of a number when it is shifted left by 1? Shifted right by 1? 4. Describe the process of using a mask to check the value of a specific bit within an
integer. 5. How can you use the bitwise AND operator (&) to check if a number is even or odd?
Explain the logic. 6. What is the difference between the logical AND (&&) and the bitwise AND (&)? Provide an example scenario for each. 7. Explain the purpose of the ~ (bitwise NOT) operator. What is the result of applying it to a mask, and how can this be useful? 1. What is the primary goal of program debugging? What types of errors can it help identify? 2. Describe the difference between Step Over (F10) and Step Into (F11) debugging commands. When would you choose one over the other? 3. What is the purpose of a breakpoint in planned debugging? How do you set and remove a breakpoint in Visual Studio? 4. Explain the utility of the "Watch" window compared to the "Autos" or "Locals" windows during a debugging session. 5. What is the key difference between the Debug and Release configurations when building a project? Why is it necessary to create a Release version after successful debugging? 6. List at least three types of files commonly found in a project's Debug folder and briefly state their purpose (e.g., *.pdb). 7. During debugging, you notice a variable has an incorrect value. How can you change its value during runtime to test a hypothesis without modifying the source code? 8. What command is used to exit the debug mode and stop the current debugging session? 1. What is an array in C++? List its three main characteristics. 2. How are array elements numbered in C++? What is the valid index range for an array declared as int data[25];? 3. Explain the difference between array declaration and initialization. Provide an example of each. 4. What is an initializer list? What happens if the initializer list is shorter than the array size? 5. How can you let the compiler automatically determine the size of an array during initialization? 6. What values do elements of a local array contain if it is declared but not explicitly initialized? How does this differ from a global array? 7. What is an array out-of-bounds error? Why is it dangerous, and what are its potential consequences? 8. How do you calculate the number of elements in an array using the sizeof operator?
Provide the formula. What is a significant limitation of this method? 9. Why is it impossible to copy the contents of one array into another using the assignment
operator (arrayB = arrayA;)? What is the correct way to perform this operation? 10. Why does comparing two arrays using the equality operator (arrayA == arrayB) not check if their elements are equal? How should array comparison be done correctly? 11. What does the name of an array represent in terms of memory? 1. What is a pointer in C++ and what are its two main attributes? 2. Explain the difference between the & and * operators when working with pointers. 3. Why is pointer initialization critical and what dangers do uninitialized pointers pose? 4. What is the fundamental relationship between arrays and pointers in C++? 5. How does pointer arithmetic work and why does ptr + 1 advance by the size of the pointed type rather than 1 byte? 6. What is the difference between an array name and a pointer variable? Why can't you increment an array name? 7. What are the differences between const int*, int* const, and const int* const? 8. How can you safely iterate through an array using pointers, and what are the boundary risks? 9. What is a null pointer and why should you check for nullptr before dereferencing? 10. How do you access array elements using pointer syntax, and how does the compiler translate arr[i] internally? 1. What is a multidimensional array? How is a two-dimensional array structured in memory? 2. Explain the concept of an "array of arrays". How does this relate to the declaration int arr/ROWS//COLS;? 3. The name of a two-dimensional array without indices is a pointer constant. What does this pointer point to? What do the expressions *(A + i) and *(*(A + i) +j) mean for a two-dimensional array A? 4. Describe the different ways to access the element A/1/[2/ of a two-dimensional array
using pointers. 5. What is the rule for omitting the size of dimensions when initializing and when passing a multidimensional array to a function? Why is it allowed to omit only the first dimension? 6. Explain the principle of "row-major order" for storing two-dimensional arrays in memory.
How does this affect element access? 7. Why are nested loops the standard tool for processing multidimensional arrays?
Describe the typical pattern for iterating through a matrix. 1. How is a character string stored in memory in C++? What is the role of the null terminator (10), and why is it critical for C-style strings? 2. Why must the size of a char array declared to hold a string be at least one greater than the number of characters you intend to store? 3. The array name without an index is a pointer constant. What does the name of a char array point to? 4. What are the two main ways to initialize a C-style string? What is a common mistake when using the initializer list method, and what is its consequence? 5. Why is it necessary to add _CRT_SECURE_NO_WARNINGS to the preprocessor definitions in Visual Studio when working with many standard C library functions?
What is the alternative approach? 6. What is the key difference between stropy and strncpy? Why might strncpy be considered safer? 7. How does the stremp function determine if one string is "less than" another? Why can't you use the == operator to compare two C-style strings for content equality? 8. Describe the purpose and parameters of the strok function. How do you get all tokens from a string? 9. What do the functions strchr and strrchr do? How do they differ? 10. Explain what the strstr function returns and what it is commonly used for. 11. What is the purpose of the functions in the < cctype> header? Give three examples of such functions and their use. 12. What is the difference between tolower(c) and_tolower(c)? When should you use each? 1. What is a function in C++? Name the three core benefits of using functions in a program. 2. What is the difference between a function declaration (prototype) and a function definition? Provide examples. 3. What is a function signature? Which elements are part of the signature, and which are not? 4. What methods of passing parameters to a function do you know? Explain the difference between pass-by-value, pass-by-pointer, and pass-by-reference. 5. Why can't you pass an array to a function by value? What is the correct way to pass an array to a function? 6. What is variable scope? How is it related to functions? 7. How does a function return a value? What happens if a function with a non-void return type does not return a value on all control paths? 8. Can you use multiple return statements in a single function? Provide an example. 9. What is function overloading? What is it based on? 10. How is interaction between functions organized in a program? Provide an example program with several functions. 11. What are default parameters? How are they specified, and in what cases are they useful? 12. How can you prevent a function from modifying the data passed to it? What modifiers are used for this? 13. What is recursion? Provide an example of a recursive function. 14. What common errors occur when working with functions? How can they be avoided? 15. How do you use pointers to functions? Provide an example of declaring and calling a function through a pointer. 用中文回答
最新发布
11-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值